Você está na página 1de 24

36

Punteros y arrays
37
I
n
t
r
o
d
u
c
c
i

n

a

l
a

P
r
o
g
r
a
m
a
c
i

n
M
a
r

a

L
u
q
u
e

R
o
d
r

g
u
e
z
Punteros a punteros

Un puntero puede apuntar a otra variable de tipo


puntero.

Declaracin:

Tipo variable ** Nombre de variable


int valor = 100;
int * ptr1= &valor;
int ** ptr2 =&ptr1;
//Asigna 95 a valor
valor=95;
//Asigna 105 a valor
*ptr1=105;
//Asigna 99 a valor
**ptr2=99;
38
I
n
t
r
o
d
u
c
c
i

n

a

l
a

P
r
o
g
r
a
m
a
c
i

n
M
a
r

a

L
u
q
u
e

R
o
d
r

g
u
e
z
Punteros a punteros
valor=95;
*ptr1=105;
**ptr2=99;
39
I
n
t
r
o
d
u
c
c
i

n

a

l
a

P
r
o
g
r
a
m
a
c
i

n
M
a
r

a

L
u
q
u
e

R
o
d
r

g
u
e
z
Ari tmti ca de punteros

Asignacin (=). Han de ser del mismo tipo, en otro


caso hay que utilizar casting.

p=q

Suma/Resta con literales(enteros).

p++ (p=p+1) //Direccin del elemento siguiente

p+=n (p=p+n)

p=p+10

p-- //Direccin del elementos anterior

Relacionales

p==q, p!=q, p<q, p>q, p==NULL, p!=NULL

Operaciones NO vlidas

Sumar, multiplicar o dividir punteros


40
I
n
t
r
o
d
u
c
c
i

n

a

l
a

P
r
o
g
r
a
m
a
c
i

n
M
a
r

a

L
u
q
u
e

R
o
d
r

g
u
e
z
Ari tmti ca de punteros

Suponiendo que ptr es un puntero a un tipo, la


expresin ptr+desplazamiento devuelve un
puntero a la posicin de memoria sizeof(tipo)*
desplazamiento bytes por encima de ptr.
41
I
n
t
r
o
d
u
c
c
i

n

a

l
a

P
r
o
g
r
a
m
a
c
i

n
M
a
r

a

L
u
q
u
e

R
o
d
r

g
u
e
z
Punteros y arrays
uni di mensi onal es

El identificador de un vector esttico es un puntero


CONSTANTE que almacena la direccin de memoria
del primer elemento del vector.
int v[3];
int *ptr;
...
ptr=&v[0]; //ptr=v

v es igual a &v[0]

*v equivale a v[0]

v[0]=6 equivale a *v=6 y a *(&v[0])=6


7 5 6
v[0]
v
ptr
x1001
x1001
x1001 x1005 x1009
42
I
n
t
r
o
d
u
c
c
i

n

a

l
a

P
r
o
g
r
a
m
a
c
i

n
M
a
r

a

L
u
q
u
e

R
o
d
r

g
u
e
z
Punteros y arrays
uni di mensi onal es

Dado que un vector v es un puntero a la primera


posicin, obedece las leyes de la aritmtica de
punteros.

v apunta a v[0]

(v+i) apunta a v[i]

*(v+i) equivale a v[i]

Recprocamente, a los punteros se les puede poner


subndices:

*(ptr+i) es equivalente a ptr[i].

Pero, recordad: Un vector es un puntero constante


int v[2]={0,1};
v++; //error de compilacin
43
I
n
t
r
o
d
u
c
c
i

n

a

l
a

P
r
o
g
r
a
m
a
c
i

n
M
a
r

a

L
u
q
u
e

R
o
d
r

g
u
e
z
Punteros y arrays
uni di mensi onal es
float vector[5]={10,20,30,40,50};
44
I
n
t
r
o
d
u
c
c
i

n

a

l
a

P
r
o
g
r
a
m
a
c
i

n
M
a
r

a

L
u
q
u
e

R
o
d
r

g
u
e
z
Punteros y arrays
uni di mensi onal es
//Distintas forma de sumar los elementos de un
vector
#define Dim 5
int main(){
int i, suma;
int *ptr, *ptrfin;
int v[Dim]={1,2,3,4,5};
/* ------------------------------*/
suma=0;
for(i=0;i<Dim;i++) {
suma=suma+v[i];
}
printf(Resultado para suma=suma+V[i]:%d\n,
suma);
suma.c
45
I
n
t
r
o
d
u
c
c
i

n

a

l
a

P
r
o
g
r
a
m
a
c
i

n
M
a
r

a

L
u
q
u
e

R
o
d
r

g
u
e
z
Punteros y arrays
uni di mensi onal es
/* ------------------------------*/
suma=0;
for(i=0;i<Dim;i++) {
suma=suma+(*(v+i));
}
printf(Resultado para suma=suma+(*(V+i)):%d\n,
suma);
/* ------------------------------*/
suma=0;
ptr=v;
for(i=0;i<Dim;i++) {
suma=suma+ptr[i];
}
printf(Resultado para suma=suma+ptr[i]:%d\n,
suma);
suma.c
46
I
n
t
r
o
d
u
c
c
i

n

a

l
a

P
r
o
g
r
a
m
a
c
i

n
M
a
r

a

L
u
q
u
e

R
o
d
r

g
u
e
z
Punteros y arrays
uni di mensi onal es
/* ------------------------------*/
suma=0;
ptrfin=v+Dim;
for(ptr=v;ptr<ptrfin;ptr++) {
suma=suma+(*ptr);
}
printf(Resultado para suma=suma+(*ptr):%d\n,
suma);
/* ------------------------------*/
suma=0;
ptr=v;
for(i=0;i<Dim;i++) {
suma=suma+(*(ptr+i));
}
printf(Resultado para suma=suma+(*(ptr+i)):
%d\n,suma);
suma.c
47
I
n
t
r
o
d
u
c
c
i

n

a

l
a

P
r
o
g
r
a
m
a
c
i

n
M
a
r

a

L
u
q
u
e

R
o
d
r

g
u
e
z
Punteros y arrays
uni di mensi onal es
/* ------------------------------*/
suma=0;
ptr=v;
for(i=0;i<Dim;i++) {
suma=suma+(*ptr++);
}
printf(Resultado para suma=suma+(*ptr++):
%d\n,suma);
return 0;
}
suma.c
Primero se aplica *
luego se aplica ++
48
I
n
t
r
o
d
u
c
c
i

n

a

l
a

P
r
o
g
r
a
m
a
c
i

n
M
a
r

a

L
u
q
u
e

R
o
d
r

g
u
e
z
Cadenas caracteres

Ejemplo. Longitud de una cadena


#include <stdio.h>
#define TOPE 30
int main() {
char cadena[TOPE]=Hola;
int i,longitud=0;
char * ptr;

//Primera versin con indices
for (i=0; cadena[i]!='\0'; i++)
longitud++;
printf(Longitud(1): %d\n,longitud);
//Segunda versin con punteros
for (ptr=cadena;*ptr!='\0';ptr++);
printf(Longitud(2): %d\n,ptr-cadena);
}
cuentaCaracteres.c
49
I
n
t
r
o
d
u
c
c
i

n

a

l
a

P
r
o
g
r
a
m
a
c
i

n
M
a
r

a

L
u
q
u
e

R
o
d
r

g
u
e
z
Cadenas. Errores comunes

Una funcin devuelve un puntero que referencia a una


variable o array declarados como locales.

Al salir de la funcin todas las variables locales


desaparecen.

No devolver nunca un puntero que apunte a una


variable declarada como local.
#include <stdio.h>
char * f1 () {
char buffer[128];
printf(Nombre: );
scanf(%s,buffer);
return(buffer);
}
int main() {
char * ptr;
ptr=f1();
printf(%s\n,ptr);
}
dangling.c
50
I
n
t
r
o
d
u
c
c
i

n

a

l
a

P
r
o
g
r
a
m
a
c
i

n
M
a
r

a

L
u
q
u
e

R
o
d
r

g
u
e
z
Cadenas errores comunes
int main() {
char cad[]=abcde;
char * ptr = cad;
//error en tiempo de ejecucin
//sobrepasamos el espacio reservado para cad
strcpy(ptr,Hasta luego cocodrilo);
}
int main() {
char * p;
//Error, no hemos reservado memoria para los
//datos apuntados por el puntero
strcpy(p,wxieldki);
printf(<%s>,p);
return 0;
}
errorCadena.c
wildPointer.c
51
I
n
t
r
o
d
u
c
c
i

n

a

l
a

P
r
o
g
r
a
m
a
c
i

n
M
a
r

a

L
u
q
u
e

R
o
d
r

g
u
e
z
Punteros y arrays
bi di mensi onal es

El nombre de la matriz M es un puntero al primer


elemento de la matriz.

int M[maxF][maxC]

En general M[i] se comporta como un puntero que


apunta al principio de la fila i de la matriz
M[0] apunta a M[0][0]
M[1] apunta a M[1][0]

Las filas de una matriz esttica se almacenan


consecutivas en memoria.
52
I
n
t
r
o
d
u
c
c
i

n

a

l
a

P
r
o
g
r
a
m
a
c
i

n
M
a
r

a

L
u
q
u
e

R
o
d
r

g
u
e
z
Punteros y arrays
bi di mensi onal es

Para averiguar dnde est M[i][j], el compilador debe


resolver la siguiente frmula de direccionamiento:
direccion(M[i][j])=direccion(M[0][0]) + i*maxC+j

i*maxC nos permite acceder a la fila correcta

j nos indica el desplazamiento dentro de la fila


53
I
n
t
r
o
d
u
c
c
i

n

a

l
a

P
r
o
g
r
a
m
a
c
i

n
M
a
r

a

L
u
q
u
e

R
o
d
r

g
u
e
z
Punteros y arrays
bi di mensi onal es

Ejemplo: este cdigo elimina los valores negativos de


una matriz bidimensional, sustituyndolos por cero.
#include <stdio.h>
#define maxF 3
#define maxC 2
int main(){
int * ptr;
int matriz[maxF][maxC]={{1,1},{-1,-1},{1,1}};
int i,j,nElem;
nElem=maxF*maxC;
ptr=matriz[0]; //ptr=&matriz[0][0]
54
I
n
t
r
o
d
u
c
c
i

n

a

l
a

P
r
o
g
r
a
m
a
c
i

n
M
a
r

a

L
u
q
u
e

R
o
d
r

g
u
e
z
Punteros y arrays
bi di mensi onal es
for (i=0; i<nElem; i++) {
if (*ptr<0) {
*ptr=0;
}
ptr++;
}
for (i=0;i<maxF;i++){
for(j=0; j<maxC; j++){
printf(matriz[%d][%d]=%d\n,i,j,matriz[i]
[j]);
}
}
La matriz se almacena en
posiciones consecutivas de
memoria
elimina.c
55
Punteros
Modularizacin
56
I
n
t
r
o
d
u
c
c
i

n

a

l
a

P
r
o
g
r
a
m
a
c
i

n
M
a
r

a

L
u
q
u
e

R
o
d
r

g
u
e
z
Modul ari zaci n con arrays

Un mdulo puede recibir como entrada un dato de tipo


vector.

void imprimeElementos(int vector[], int tope);

Dado que un vector es un puntero, la siguiente


cabecera tambin sera vlida.

void imprimeElementos(int * vector, int tope);

No ocurre lo mismo con los arrays bidimensionales


estticos. Las siguientes cabeceras no son
equivalentes.

void imprimeMatriz(int m[][maxC], int f, int c);

void imprimeElementos(int ** m, int f, int c);


57
I
n
t
r
o
d
u
c
c
i

n

a

l
a

P
r
o
g
r
a
m
a
c
i

n
M
a
r

a

L
u
q
u
e

R
o
d
r

g
u
e
z
Modul ari zaci n con vectores

Varias formas de pasar vectores estticos a funciones


//Primera versin: especificacin del tamao
void f1(int vector[NUM_ELEMENTOS], int tope)
{
int i;
for (i=0;i<tope;i++)
printf(%d,vector[i]);
}
//Segunda versin: sin especificar el tamao
void f2(int vector[], int tope) {
int i;
for (i=0;i<tope;i++)
printf(%d,vector[i]);
}
pasoVectores.c
58
I
n
t
r
o
d
u
c
c
i

n

a

l
a

P
r
o
g
r
a
m
a
c
i

n
M
a
r

a

L
u
q
u
e

R
o
d
r

g
u
e
z
Modul ari zaci n con vectores
//Tercera versin: puntero al primer elemento
void f3(int * vector, int tope) {
int i;
for (i=0;i<tope;i++)
printf(%d,vector[i]);
}
//Cuarta versin: puntero al primer elemento
void f4(int * vector, int tope) {
int i, *ptrfinal,*ptr;
ptrfinal=vector+tope;
for (ptr=vector;ptr<ptrfinal;ptr++)
printf(%d,*ptr);
}
pasoVectores.c
59
I
n
t
r
o
d
u
c
c
i

n

a

l
a

P
r
o
g
r
a
m
a
c
i

n
M
a
r

a

L
u
q
u
e

R
o
d
r

g
u
e
z
Modul ari zaci n con vectores

Al hacer el paso de un vector a una funcin, decimos


que se hace POR REFERENCIA.

El vector en s (el puntero al primer elemento), se pasa por


valor, no puede cambiar la direccin de comienzo del vector.

Los elementos apuntados por el vector si que pueden ser


modificados y ese cambio se ver fuera de la funcin
void modulo(int vector[], int tope){
int i;
for (i=0;i<tope;i++) {
//Modifica los elementos apuntados
vector[i]=vector[i]+7;
}
}

Você também pode gostar