Sunteți pe pagina 1din 34

PUNTEROS

Dato: Porcin de informacin manejable por el computador.


Tipos de datos: Formados por el conjunto de espacio de
representacin y conjunto de operaciones asociadas.
Simples Carcter, entero, Real, Puntero
Estructurados o compuestos:
Estticos: Su espacio en memoria es reservado en tiempo de compilacin.
Dinmicos: Su espacio en memoria es reservado en tiempo de ejecucin.
Contiguos: Se guardan en memoria de forma consecutiva (vectores, matrices).
Enlazados: No se guardan en memoria de forma consecutiva (listas, rboles).

TIPOS ESTTICOS
(short, int, char, [], etc.) Se almacenan de forma esttica en la memoria del ordenador,
destinando memoria para este tipo de variables en tiempo de compilacin.

Ventajas
Sencillos de manejar y no dan problemas en tiempo de ejecucin.
Desventajas
No pueden crecer o menguar durante la ejecucin del programa (hay que hacer
estimaciones previas a la codificacin).
Las zonas de memoria asignadas a estas variables son fijas (no son adecuadas
para representar listas, rboles, etc.).
SIS - 1101 ING. CARLOS BALDERRMA VSQUEZ PAG. 1 DE 34
Los punteros proporcionan los medios por los cuales las funciones pueden
modificar sus argumentos de llamada.
El uso de punteros puede mejorar la eficiencia de las rutinas
A menudo se emplean punteros como soporte de ciertas estructuras de datos
como ser listas enlazadas y rboles.
Un puntero es una variable de tipo simple, que almacena como valor una
direccin de memoria, que suele estar ocupada por otro dato diferente. El
puntero, pues, apunta o referencia a otro dato.














SIS - 1101 ING. CARLOS BALDERRMA VSQUEZ PAG. 2 DE 34
Se declaran mediante el operador * y el tipo de dato al que apuntar. Tambin es
posible usar punteros sin tipo definido (void *) indicando luego durante la
asignacin a qu tipo de dato apuntan.
Pueden usarse arrays de punteros o punteros a/dentro de estructuras.

SINTAXIS





Tipo_dato
*
variable
*
,
variable
;
Puntero: tipo de dato que representa una direccin de memoria
SIS - 1101 ING. CARLOS BALDERRMA VSQUE
variables a las que puede apuntar el puntero
Z PAG. 3 DE 34
Cmo se define
tipo * nombre;







El tipo base del puntero define el tipo de las
cualquier
tipo
valido en C
(tipo base)
Indica que nombre
contendr la direccin de
memoria
de una variable de
tipo tipo
Nombre de la
variable puntero
Operadores de Punteros:
&: Operador unario que devuelve la direccin de memoria de su
operando
*: Operador unario que devuelve (el valor de) la variable localizada en la
direccin indicada por su operando

&var Es la direccin de var
*var Es el contenido del objeto apuntado por var,
& y * son operadores complementarios
Ejemplos:
int x, y;
int * p;
Sentencias validas:
x = 1;
y = 2;
p = &x; //p guarda la direccin de memoria donde est x
Para acceder al contenido de una variable (x) a travs de un puntero (p) se usa el
operador *:
int z;
z = *p;
guarda en la variable entera z el contenido (no la direccin!!) de la zona de memoria
apuntada por p, es decir, z guarda un valor entero, en este caso 1.
SIS - 1101 ING. CARLOS BALDERRMA VSQUEZ PAG. 4 DE 34
Cuidado con las confusiones!!:

int x = 1, y = 2, z[10];
int * p, * q;
p = &x;
q = &y;
*q = *p; // Esto equivale a y = *p

(Reasignacin de valores enteros)
q = p;


(q apunta a donde apunte p)
Son asignaciones vlidas: *p = 0;


Pone en la zona de memoria apuntada por p el valor entero 0.

p = &z[0];

Pone en p la direccin de memoria donde se encuentra la variable entera z[0].


SIS - 1101 ING. CARLOS BALDERRMA VSQUEZ PAG. 5 DE 34
#include <stdio.h>
int main ()
{ int a = 5; int *pa = &a;
printf("Direccin de a = %lu\n", &a);
printf("Direccin de pa = %lu\n\n", &pa);
printf("Valor de a = %d\n", a);
printf("Valor de *pa = %d\n", *pa);
printf("Probando que & y * son operaciones complementarias\n");
printf("&*pa = %lu\n", &*pa);
printf("*&pa = %lu\n", *&pa);
printf("*&a = %d\n", *&a);
}
#include<stdio.h>
#include<conio.h>
main()
{
int a=10,*b;
clrscr();
printf("Valor de a = %4d\nDireccin de a= %6x\nContenido de b= %4d\nDireccin de b=
%6x",a,&a,*b,b);
b=&a;
printf("\nDespues de la asignacin\nContenido de b=%4d\nDireccin de b= %6x ",*b,b);
*b=7;
printf("\nDespues de la Asignacin \nContenido de a= %d ",a);
getch();
SIS - 1101 ING. CARLOS BALDERRMA VSQUEZ PAG. 6 DE 34
}
ARITMTICA DE PUNTEROS
Existen cuatro operadores que se pueden aplicar a punteros:


La aritmtica de punteros est referida a su tipo base. int x, *p;
p es un puntero a entero. Supongamos que tiene un valor de 2000, direccin de
memoria 2000. Supongamos que un entero ocupa 4 bytes. Entonces:



Cada vez que se INCREMENTA (o DECREMENTA) un puntero, apunta a la
posicin de memoria del elemento SIGUIENTE (o ANTERIOR) de su tipo base.




Sobre los objetos apuntados puede hacerse cualquier operacin que sea legal para
tales objetos, pero con los propios punteros solo se pueden hacer las operaciones
aritmticas de suma y resta de enteros. As:
NO se pueden MULTIPLICAR o DIVIDIR punteros.
NO se les puede aplicar el DESPLAZAMIENTO a nivel DE BITS.
NO se les puede SUMAR o RESTAR un float o un double
SIS - 1101 ING. CARLOS BALDERRMA VSQUEZ PAG. 7 DE 34
COMPARACIN DE PUNTEROS
Pueden compararse dos punteros en una expresin relacional:
if (p < q)
printf("p apunta a memoria ms baja que q\n");

Esto es til cuando dos o ms punteros apuntan a un objeto (estructurado )comn:
Si p.ej. p y q apuntan a elementos de un vector:
p<q cierto si el elemento al que apunta p est antes que el que apunta q.

Son vlidos los operadores: ==, !=, <, >, <=, >=

q - p cuenta el nmero de elementos entre p y q cuando p y q apuntan a elementos de
una matriz.

PUNTEROS NO INICIALIZADOS: NULL
NULL es el valor para punteros que no apuntan a ningn sitio.
int x = 1, *p;
p = &x;
p = NULL;
Despus de asignarle NULL, p podr a apuntar de nuevo a variables enteras:
int y = 2;
p = &y;
SIS - 1101 ING. CARLOS BALDERRMA VSQUEZ PAG. 8 DE 34
PASO DE PARMETROS EN C
Por defecto, en C se pasan los parmetros a las funciones siempre por valor, de forma
que no cambian su valor al salir de la funcin. Pero si en lugar de pasar un argumento
pasamos un puntero al argumento, simulamos el paso por referencia, de forma que los
argumentos pueden entrar con un valor y salir con otro.
Pasar un puntero a una variable por valor (la nica forma posible en C) equivale a
pasar esta variable por referencia.

#include <stdio.h> /* Por valor */
int incrementa(int base, int incr);
int a;
int main()
{
a = incr(a, 5);
. . .
}
int incrementa(int base, int incr)
{
return (base + incr);
}
#include <stdio.h> /* Por
referencia */
void incrementa(int * base, int
incr);
int a;
int main()
{
incr(&a, 5);
. . .
}
void incr(int * base, int incr)
{
*base +=incr;














SIS - 1101 ING. CARLOS BALDERRMA VSQUEZ PAG. 9 DE 34
EJEMPLO DE PASO POR REFERENCIA

Ejemplo: Funcin intercambia, que se implementa para intercambiar el valor de sus
dos argumentos enteros:


void intercambia (int * x, int *
y)
{
int temporal;
temporal = *x;
*x = *y;
*y = temporal;
}
#incluye <sodio.h>
#incluye <conio.h>
void intercambi (int * x, int * y) ;
int main ()
{
int x, y;
x = 10;
y = 20;
intercambia(&x, &y);
}


CUIDADO!!: es incorrecto realizar la llamada: intercambia(x, y);

SIS - 1101 ING. CARLOS BALDERRMA VSQUEZ PAG. 10 DE 34
PASO DE PARMETROS EN C++

El lenguaje C++ ofrece una alternativa ms elegante y segura para el
paso de parmetros por referencia: tipo referencia.
Se declaran: tipo & nombre;
int i;
int &r = i;

PASO DE PARMETROS POR REFERENCIA:
La forma de invocar a la funcin es la misma tanto si el parmetro se pasa por
referencia como si se pasa por valor.
En el prototipo de la funcin se sustituye la declaracin de los punteros por tipos
referencia (* cambiando por &)
#include<stdio.h>
void intercambia (int & x, int & y)
{
int temporal;
temporal = x;
x = y;
y = temporal;
}

#include<conio.h>
void intercambia(int & x, int & y);
int main ()
{
int x, y;
x = 10;
y = 20;
intercambia(x, y);
SIS - 1101 ING. CARLOS BALDERRMA VSQUEZ PAG. 11 DE 34
}
FUNCIONES DE GESTIN DINMICA DE MEMORIA

Estructuras estticas: Su tamao tiene que ser conocido en tiempo de
compilacin. El espacio de memoria que ocupan es reservado antes de la
ejecucin del programa.
Estructuras dinmicas: Su tamao no se conoce hasta el tiempo de ejecucin.
Adems, no tiene por que ser fijo, sino que lo modifican segn necesidad.

GESTIN DINMICA DE MEMORIA: FUNCIONES

Reserva de memoria: malloc y calloc.
Liberacin de memoria: free.
Reasignacin de memoria: realloc

SIS - 1101 ING. CARLOS BALDERRMA VSQUEZ PAG. 12 DE 34
Reserva de memoria: malloc



Argumentos:
tam: tamao en bytes del bloque de memoria a reservar.
Valores de retorno: puntero al primer byte del bloque reservado, si xito. En caso
contrario, NULL.
Prototipo: en stdlib.h

Al utilizar malloc es muy importante: Comprobar que el puntero devuelto no es un
puntero nulo antes de usarlo.

#include <stdio.h>
#include <stdlib.h>
void reserva_memoria(void)
{ int *p;
p = malloc(sizeof(int));
if (p == NULL) { fprintf(stderr, "Memoria insuficiente\n"); exit(1); }
}


SIS - 1101 ING. CARLOS BALDERRMA VSQUEZ PAG. 13 DE 34
Reserva de memoria: calloc


Argumentos:
num: nmero de elementos del array a reservar.
tam: tamao en bytes de cada elemento del array.
Valores de retorno: puntero al primer byte del bloque reservado, si xito. En caso
contrario, NULL.
Efecto: Reserva un bloque de memoria para num elementos, cada uno de tamao tam
bytes.
Prototipo: en stdlib.h
#include <stdio.h>
#include <stdlib.h>
int * reserva_memoria(int num_elementos)
{ int * pt;
pt = calloc(num_elementos,sizeof(int));
if (pt == NULL) { fprintf(stderr, "Memoria Insuficiente\n"); exit(1); }
return pt;
}
Aspectos a resaltar:El moldeado del valor devuelto por calloc. El uso del operador
sizeof para calcular el tamao requerido. La comprobacin del valor devuelto por
calloc
SIS - 1101 ING. CARLOS BALDERRMA VSQUEZ PAG. 14 DE 34
Liberacin de memoria: free


Argumentos:
puntero: debe contener la direccin del primer byte de un bloque
previamente reservado con malloc o calloc.
Efecto: Libera la zona de memoria apuntada por puntero.
Prototipo: en stdlib.h
Consideraciones respecto a su uso:
Respetar la precondicin de uso. se hace as, puede haber problemas.
Despus de la liberacin el puntero queda invalidado. No se puede usar. En
particular, NO se puede liberar dos veces el mismo bloque de memoria.
Es conveniente asignar NULL al puntero despus de la llamada a free

p = reserva memoria(20);
int * p;

char * p;
p = malloc(sizeof(char)*200);

free(p); p = NULL;

SIS - 1101 ING. CARLOS BALDERRMA VSQUEZ PAG. 15 DE 34
#include <stdio.h>
#include <stdlib.h>
int main()
{ char * nombres[50];
int j;
for (
j = 0; j < 50; j++)
{
nombres[j] = calloc(40, sizeof(char));
if (nombres[j] == NULL)
{
fprintf(stderr, "Memoria insuficiente\n");
exit(1);
}
gets(nombres[j]);
}
for (j = 0; j < 50; j++)
{
free(nombres[j]);
}
}


SIS - 1101 ING. CARLOS BALDERRMA VSQUEZ PAG. 16 DE 34
Reasignacin de memoria: realloc




Argumentos:
puntero: debe contener la direccin del primer byte de un bloque
previamente reservado con malloc o calloc.
nuevotam: nuevo tamao en bytes del bloque de memoria a reservar.
Valores de retorno: puntero al primer byte del bloque reservado, si xito. En caso
contrario, NULL.

Efecto: Reserva un nuevo bloque de memoria del tamao requerido, que puede ser
mayor o menor que el anterior. Copia un nmero de bytes del bloque original igual al
mnimo del tamao original y el nuevo tamao. Despus libera el bloque original
invalidando cualquier puntero a ste. Si no es posible la nueva reserva, devuelve
NULL y no afecta al bloque original.

Prototipo: en stdlib.h
SIS - 1101 ING. CARLOS BALDERRMA VSQUEZ PAG. 17 DE 34
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{ char saludo[] = "Hola";
char nombre[] = "Juan";
char * ptr; int i;
ptr = malloc(5 * sizeof(char));
if (ptr == NULL) {
fprintf(stderr, "Memoria Insuficiente\n"); exit(1);
}
strcpy(ptr, saludo); printf("%s\n", ptr);
ptr = realloc(ptr, 10 * sizeof(char));
if (ptr == NULL) {
fprintf(stderr, "Memoria Insuficiente\n");
exit(1);
}
strcat(ptr, nombre); printf("%s\n", ptr);
free(ptr);
}
SIS - 1101 ING. CARLOS BALDERRMA VSQUEZ PAG. 18 DE 34
PUNTEROS Y ARRAYS
Existe una estrecha relacin entre ambos.
char cad[80], * p1;
p1 = cad;
p1 guarda la direccin de memoria del primer elemento del array cad.



Acceso al 3er elemento de cad:
cad[2] *(p1 + 2)
Cualquier operacin con ndices se puede hacer con punteros.
Cundo usar unos u otros?:
Si se accede al vector en orden ascendente o descendente estricto: punteros.
Si se accede al vector aleatoriamente: ndices

int a[10];
int * pa;
pa = &a[0] pa = a;

* ( <puntero> + <valor> )
Si pa apunta al i-simo elemento de a, pa + 1 apunta al siguiente elemento
independientemente del tipo base del array:
*pa a[0]; *(pa + 1) a[1]; . . . *(pa + i) a[i];
SIS - 1101 ING. CARLOS BALDERRMA VSQUEZ PAG. 19 DE 34
El nombre de un array usado como puntero es una constante que siempre apunta a la
misma direccin de memoria (la posicin del primer elemento del array, a[0]).

int a, b; int tabla[20]; int * ptabla;

Es lo mismo usar tabla que &tabla[0]. Cuando se pasa un nombre de array a una
funcin
se pasa la direccin del elemento 0 (inicial) el paso de arrays es por referencia.
tabla++ es incorrecto porque tabla es una constante.
ptabla = tabla; ptabla = &tabla[0];
a = *(ptabla+4); a = tabla[4];
scanf("%d", ptabla + 6); scanf("%d", &tabla[6]);
printf("%d", *(ptabla + 5); printf("%d", tabla[5]);
ptabla++ hace que ptabla apunte al segundo elemento del array
Cmo pasar a una funcin parte de un array?
int a[10]; int * p;
p = &a[3];
Declaracin de la funcin:
f (int p[]) f (int * p)
{... {...
} }
Llamada:
f(&a[3]); f(a+3);







SIS - 1101 ING. CARLOS BALDERRMA VSQUEZ PAG. 20 DE 34

/* Rotacion de los elementos de un vector */
#include "stdio.h"
#define n 10
void impr(int *arr,int m)
{int i;
for (i=0;i<m;i++) printf("%d ",*(arr+i));
printf("\n");
}
main()
{int r,x=n,y,z[n]={0,1,2,3,4,6,7,8,9,10,};
int *p1,*p2;
impr(z,n);p1=z;
printf("Ingrese Nro de Rotaciones
");scanf("%d",&r);
for (y=0;y<n;y++)
{
if (y<n-r+1)
z[y]=z[y+r-1];
else
z[y]=z[y-r];
}
impr(z,n);
}

/* N Rotacion de los elementos de un vector*/
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#define n 9
#define c 3
void impr(int *arr,int m);
main()
{ int aux,x=0,y,z[n]={0,1,2,3,4,6,7,8,9};
clrscr();
impr(z,n);
while (x++<10)
{
aux=z[n-1];
for (y=n-1;y>0;y--)
z[y]=z[y-1];
z[0]=aux;
impr(z,n);
getch();
}
getch();
}
void impr(int *arr,int m)
{ int i;
for (i=0;i<m;i++) printf("%d ",*(arr+i));
printf("\n");
}



























SIS - 1101 ING. CARLOS BALDERRMA VSQUEZ PAG. 21 DE 34
PUNTEROS Y CADENAS DE CARACTERES

Las cadenas de caracteres son arrays de tipo char en las que el carcter
siguiente al ltimo vlido es '\0'. Las cadenas de caracteres constantes van
delimitadas por comillas dobles: "...".






La primera expresin es una cadena y emplea dos caracteres. La segunda es un nico
carcter.
Siempre ha de aparecer el carcter '\0' por lo que al hacer la reserva de memoria hay
que incluir un carcter extra: char nombre cadena[tamao + 1];
Acceso a los caracteres
char letras[6] = "ABCDE";


Como en todo vector :
letras &letras[0]

SIS - 1101 ING. CARLOS BALDERRMA VSQUEZ PAG. 22 DE 34
Acceso a los caracteres individuales
char cadena[12] = "HOLA MUNDO:";












Iniciacin de cadenas



El compilador aade el carcter '\0' al final.
char nombre[10] = "JUAN";
char saludo[5] = "HOLA";
char despedida[6] = "ADIOS";
SIS - 1101 ING. CARLOS BALDERRMA VSQUEZ PAG. 23 DE 34
Tambin como cualquier otro array, pero hay que aadir el carcter '\0' de forma
expresa:
char cadena[tamao] = {'car1', 'car2', ..., 'carN', '\0' };
char saludo[5] ={'H', 'O', 'L', 'A', '\0' };
'\0' ocupa la posicin siguiente al ltimo carcter, que no tiene por qu coincidir con
la ltima posicin reservada para la cadena. char nombre[8] = "JUAN";

















SIS - 1101 ING. CARLOS BALDERRMA VSQUEZ PAG. 24 DE 34
#include <stdio.h>
char cadena[] = "Hola";
int main()
{ char * ptr;
ptr = cadena;
printf("La cadena es %s\n",
ptr);
printf("Los caracteres son:\n");
printf("%c\n", *ptr);
printf("%c\n", *(ptr + 1));
printf("%c\n", *(ptr + 2));
printf("%c\n", *(ptr + 3));
printf("%c\n", *(ptr + 4));
#include <stdio.h>
char cadena[] = "Hola";
int main()
{ printf("La cadena es %s", cadena);
printf("Los caracteres son:\n");
printf("%c\n", cadena[0]);
printf("%c\n", cadena[1]);
printf("%c\n", cadena[2]);
printf("%c\n", cadena[3]);
printf("%c\n", cadena[4]);
}

SIS - 1101 ING. CARLOS BALDERRMA VSQUEZ PAG. 25 DE 34
#include <stdio.h>
main()
{ unsigned int dia,mes,anno;
char *m;
char *nombre_mes(unsigned int mm);
printf("Introducir fecha dd-mm-aaaa: ");
/* Los datos se separan por '-'*/
scanf("%d-%d-%d",&dia,&mes,&anno);
m=nombre_mes(mes);
printf("\n\nMes: %s",m);
}
char *nombre_mes(unsigned int mm)
{
/* Array de punteros a cadenas de caract*/
static char *mes[]={"Mes no correcto","Enero","Febrero","Marzo",
"Abril", "Mayo","Junio","Julio","Agosto",
"Septiembre","Octubre","Noviembre","Diciembre"};
return((mm>0 && mm<=12)? mes[mm]:mes[0]);
}
Punteros y Arrays Multidimensionales

El nombre del array es la direccin del primer elemento de dicho array
int matriz[10][7];
int * pmatriz;
pmatriz = &matriz[0][0];

Para referenciar un elemento mediante un puntero hay que direccionarlo: Si el array
tiene f filas y c columnas, el elemento que ocupa la posicin (j, k) ser:
*(*(nombre_puntero + j) +k)
Ejemplo:
int temp[5][5];
temp[3][5] equivale a *(*(temp + 3)+ 5)
static int dias[2][12] = { { 31, 28, 31, 30, 31},
{ 30, 31, 31, 30, 31},
{ 30, 31, 31, 29, 31},
{ 30, 31, 30, 31, 31},
{ 30, 31, 30, 31, 31} }
La formula genrica es

*(*(nombre + fila) + columna)


SIS - 1101 ING. CARLOS BALDERRMA VSQUEZ PAG. 26 DE 34
SIS - 1101 ING. CARLOS BALDERRMA VSQUEZ PAG. 27 DE 34
#include <stdio.h>
#include <conio.h>
sum(int *pu,int n)
{ int j,s=0;
for(j=0;j<n;j++)
s+=*(pu+j);return(s);
}
void imprimir(int *pu,int n)
{ int i,j;
for (i=0;i<n;i++)
{ for (j=0;j<n;j++)
printf("%d ",*((pu+i)+j*n));
printf("\n");
}
}
main()
{ int i,j,*p,*p1;
clrscr();
static int vec[4][4]={{1,1,1,1},{2,2,2,2},
{3,3,3,3},{4,4,4,4}};
p=&vec[0][0];
for (i=0,p=&vec[0][0];i<4;i++,p+=4)
printf("La suma de la fila %d es
%d\n",i+1,sum(p,4));
getch();
p=&vec[0][0];
imprimir(p,4);
getch();
}
#include <stdio.h>
#include <conio.h>
int *p;a[10],i,j,n=5;
void leer(int *x,int y)
{
int aux;
for (i=0;i<y;i++)
{
scanf("%d",&aux);
*(x+i)=aux;
};
};
void impre(int *x,int y)
{ for (i=0;i<y;i++)
printf("%8d",*(x+i));
};
void modif(int *x,int y)
{ for (i=0;i<y;i++)
if (*(x+i)%2==0)
*(x+i)=100;
};
main()
{ clrscr();
leer(a,n);
impre(a,n);
modif(a,n);
impre(a,n);
}
#include<stdlib.h>
#include<iostream.h>
#include<conio.h>
int m[10],f,c,n=5;
void leer(void)
{
for (f=0;f<n;f++)
for (c=0;c<n;c++)
*(m+f)=random(10)+1;
}
void mos(void)
{
for (f=0;f<n;f++)
cout << *(m+f) << " ";
}
main()
{
randomize();
clrscr();
leer();
getch();
mos();
getch();
}
Punteros a Estructuras

Tambin se puede apuntar directamente a estructuras, cambiando el operador punto
(.) por el flecha (->)

#include <stdio.h>
struct per
{ int cod;
char nom[10];
};
typedef struct per perso;
perso reg1,reg2={12,"juan"};
void leer(perso *x)
{ printf("\ncodigo :");scanf("%d",&x->cod);
printf("\nnombre :");scanf("%s",x->nom);
};
void impre(perso *x)
{ printf("\ncodigo :%d",x->cod);
printf("\nnombre :%s",x->nom);
};
main()
{ impre(&reg2);
leer(&reg1);
impre(&reg1);
return 0;
}
#include<stdio.h>
#include<stdlib.h>
struct fecha {
unsigned int dd,mm,aa;
};
escribir(struct fecha *f)
{ printf("Dia %u del mes %u del ao %u",
f->dd,f->mm,f->aa);
}
main()
{
struct fecha *hoy;
hoy=(struct fecha *)malloc(sizeof(struct fecha));
printf("Introducir fecha dd-mm-aa");
scanf("%u-%u-%u",&hoy->dd,
&hoy->mm,&hoy->aa);
escribir(hoy);
}
SIS - 1101 ING. CARLOS BALDERRMA VSQUEZ PAG. 28 DE 34
LISTAS ENLAZADAS SIMPLES
Una lista lineal es un conjunto de elementos de un tipo de dato que se encuentran ordenados y pueden
variar en su numero.
Las listas enlazadas pueden ser simples, dobles o circulares. En la materia ver slo las listas simples.
Las operaciones que se pueden realizar con listas enlazadas son:
Insertar, eliminar y localizar un elemento.
Determinar el nmero o tamao de la lista.
Recorrer la lista para determinar a un determinado elemento.
Clasificar los elementos de la lista en orden ascendente o descendente.
Unir dos o ms listas en una sola.
Dividir una lista en varias sublistas.
Copiar la lista y borrar la lista






















SIS - 1101 ING. CARLOS BALDERRMA VSQUEZ PAG. 29 DE 34
void instrucciones(void)
{ printf("Elija una opcion :\n"
" 1 insertar \n" " 2 eliminar \n"
" 3 mostrar \n" " 4 salir\n");
}
#include <stdio.h>
#include <stdlib.h>
struct listanodo{
int data; struct listanodo *nextptr;
};
typedef struct listanodo LISTANODO;
void printlista(LISTANODOPTR currentptr)
{ if (currentptr == NULL)
printf("Lista vacia \n\n");
else { printf("La lista es: \n");
while (currentptr != NULL) {
printf("%d --> ",currentptr -> data);
currentptr = currentptr -> nextptr;
} printf("NULL \n\n");
}
}

typedef LISTANODO *LISTANODOPTR;
void insert(LISTANODOPTR *, int);
char delete(LISTANODOPTR *, int);
int isempty(LISTANODOPTR);
void printlista(LISTANODOPTR);
void instrucciones(void);
main()
{ LISTANODOPTR startptr = NULL;
int op; int item;
do{ clrscr(); instrucciones();
printf("? "); scanf("%d", &op);
switch (op) {
case 1: printf("Introduzca el elemento: "); scanf("\n %d", &item); insert(&startptr, item);
printlista(startptr); break;
case 2: if (!isempty(startptr)) { printf("Elemento a borrar: "); scanf("\n%d", &item);
if (delete(&startptr, item)) { printf("%d borrado", item); printlista(startptr);
} else printf("%d no existe \n\n",item);
} else printf("Lista esta vacia\n\n"); break;
int isempty(LISTANODOPTR sptr)
{
return sptr == NULL;
}
case 3: printlista(startptr); break;
}
getch();
}while (op != 4); getch(); return 0;
SIS - 1101 ING. CARLOS BALDERRMA VSQUEZ PAG. 30 DE 34
}





























void insert(LISTANODOPTR *sptr, int valor)
{
LISTANODOPTR newptr, previusptr, currentptr;
newptr = malloc(sizeof(LISTANODO));
if (newptr != NULL) {
newptr->data = valor;
newptr->nextptr = NULL;
previusptr = NULL;
currentptr = *sptr;
while (currentptr != NULL && valor > currentptr ->
data) {
previusptr = currentptr;
currentptr = currentptr -> nextptr;
}
if (previusptr == NULL) {
newptr -> nextptr = *sptr;
*sptr = newptr;
}
else {
previusptr -> nextptr = newptr;
newptr -> nextptr = currentptr;
}
}
else
printf("%d no es insertado, memoria
insuficiente", valor);
}
char delete(LISTANODOPTR *sptr, int valor)
{
LISTANODOPTR previusptr, currentptr, tempptr;
if (valor == (*sptr) -> data) {
tempptr = *sptr;
*sptr = (*sptr) -> nextptr;
free(tempptr);
return(valor);
} else {
previusptr = *sptr;
currentptr = (*sptr) -> nextptr;
while (currentptr != NULL && currentptr -> data !=
valor) {
previusptr = currentptr;
currentptr = currentptr -> nextptr;
}
if (currentptr != NULL) {
tempptr = currentptr;
previusptr -> nextptr = currentptr -> nextptr;
free(tempptr);
return(valor);
}
}
return '\0';
}




SIS - 1101 ING. CARLOS BALDERRMA VSQUEZ PAG. 31 DE 34
#include <stdio.h>
void crear(elem *x)
{
*x=NULL;
clrscr();
printf("\t\tLista Creada \n\n");
};
#include <conio.h>
#include <stdlib.h>
struct nodo
{
int info;
struct nodo *sig;
};

void destruye(elem *x)
{
*x=NULL;
clrscr();
printf("\t\tLista Destruida \n\n");
};
typedef struct nodo nod;
typedef nod *elem;
elem raiz;

main()
{ int sw;
clrscr();
do {
void impre(elem x)
{
clrscr();
printf("\t\t Contenido de la Lista\n\n");
while (x!=NULL)
{
printf("-->%d",x->info);
x=x->sig;
};
printf("->NULL\n");
getch();
};
sw=menu();
switch (sw) {
case 1:crear(&raiz);impre(raiz);break;
case 2:inse(&raiz);break;
case 3:eli(&raiz);break;
case 4:impre(raiz);break;
case 5:busca(&raiz);break;
case 6:destruye(&raiz);impre(raiz);break;
};
} while(sw!=7);
return 0;
SIS - 1101 ING. CARLOS BALDERRMA VSQUEZ PAG. 32 DE 34
}

menu(void)
{ int op=0;
do {
clrscr();
printf("menu\n");
printf("1-> Crear la Lista\n");
printf("2-> Inserta elementos\n");
printf("3-> Elimina elementos\n");
printf("4-> Muestra la Lista\n");
printf("5-> Busca en la Lista\n");
printf("6-> Elimina la Lista\n");
printf("7-> Salir\n");
printf("Su opcin -> ");
scanf("%d",&op);
}while (op>7);
return op;
}





void inse(elem *x)
{ int dato; nod *aux,*aux1; elem pt,pt1;
clrscr();
printf("\tInsertar datos a la lista\n\n");
printf("Dato a insertar : "); scanf("%d",&dato);
aux=(elem) malloc(sizeof (struct nodo));
aux->info=dato;
aux->sig=NULL;
pt=NULL;pt1=*x;
while (pt1!=NULL && dato>pt1->info)
{ pt=pt1; pt1=pt1->sig; };
if (pt==NULL)
{ aux->sig=*x;
*x=aux;
}
else
{ aux->sig=pt1;
pt->sig=aux;
};
};
























SIS - 1101 ING. CARLOS BALDERRMA VSQUEZ PAG. 33 DE 34

void eli(elem *x)
{ int dato;
elem aux,pt,pt1;
clrscr();
printf("\t\tEliminacin de elementos de la lista\n");
printf("\nInto Dato a Eliminar : ");
scanf("%d",&dato);
pt=NULL;pt1=*x;
while (pt1!=NULL && dato!=pt1->info)
{ pt=pt1; pt1=pt1->sig; };
if (pt1==NULL)
{ printf("\nno hay nodo \n");
getch();}
else
{ aux=pt1;
if (pt==NULL) *x=pt1->sig;
else pt->sig=pt1->sig;
free(aux);
};
};


void busca(elem *x)
{ int dato,pos=1;
elem aux,pt,pt1;
clrscr();
printf("\t\tBusqueda en la lista\n");
printf("\nInto Dato a Buscar : ");
scanf("%d",&dato);
pt=NULL;pt1=*x;
while (pt1!=NULL && dato!=pt1->info)
{
pt=pt1; pt1=pt1->sig;
pos++;
};
if (pt1==NULL)
{ printf("\n\t\tNo Existe el dato \n");
getch();}
else
{
printf("\n\t\Existe el elemento\n");
printf("En la posicin : %2d",pos);
getch();
};
};



SIS - 1101 ING. CARLOS BALDERRMA VSQUEZ PAG. 34 DE 34

S-ar putea să vă placă și