Sei sulla pagina 1di 10

Lenguaje C

Apuntadores (punteros - pointers en ingls)


Variables y Memoria
La memoria del computador es como una largusima lnea (1 dimensin) en la que se guardan pulsos (dgitos 0 y 1), all solo se puede
avanzar para adelante y para atrs; lo cual es muy limitado para guardar datos del mundo real: nmeros, caracteres, dibujos, sonidos,
imgenes, video, etc. Para ello se clasifica la memoria en segmentos:
tipo 1

tipo 2

tipo 3

Cada tipo de segmento pueden interpretarse como nmeros, caracteres, imgenes, etc. A veces un tipo de segmento tiene varias
interpretaciones, por ejemplo, un segmento que contenga 1000001 puede ser interpretado como 65 10 o como 4116 o como la letra A; para
hacer esto, solo escribimos :
int n = 65;
Memoria RAM
n
...01011 1000001 01100..
0x7ff...c (direccin de n en base hexadecimal)
En la realidad solo existen los nmeros 0 y 1; las indicaciones en rojo sirven para darnos informacin que nos ayuda a comprender
En tiempo de ejecucin, el sistema operativo, ubica a n en una posicin disponible, por ejemplo, 0x7ff...c. De corrida en corrida, es casi
seguro que esta posicin cambie. El programador no maneja esas posiciones, hasta ahora no ha sido importante; pero pronto veremos
aplicaciones muy importantes del manejo (indirecto) de las posiciones.
Preparemos las herramientas: Ya hemos utilizado en modo limitado dos operadores:
Operador &: suministra la direccin de una variable, por ejemplo:
printf(%p\n, &n);
Salida: 0x7ff...c
Operador *: suministra el contenido de una direccin, por ejemplo:
printf(%d\n, *&n);
Salida: 65
En resumen:
Operador Descripcin
&
Operador de direccin (referencia)
: &n = direccin de n = 0x7ff...c
*
Operador de indireccin (dereferencia): *&n = valor de la direccin de n = 65
* es casi el inverso de &: *&n = *(&n) = n; pero &*n no compila.

Apuntador
Un apuntador ptr es una variable, como cualquier otra, diseada para guardar la direccin de otra variable, ejemplo, dada una variable:
int n = 65;
Podemos guardar en ptr la posicin de n:
ptr = &n;
Como de costumbre, podramos definir y asignar valor a la variable ptr as:
puntero ptr = &n;
Para mayor precisin, debemos indicar que ptr guarda direcciones de variables de tipo int; entonces podramos precisar:
int puntero ptr = &n;
Lo mismo sucedera para otros tipos de variables, ejemplo:
float datoFloat;
float puntero ptrf = &datoFloat;

// para cada tipo de dato se tendra un puntero

En la prctica estamos creando duplicando los tipos de datos:


int puntero ptr;
float puntero ptrf;
..

PGINA: 1

Lenguaje C
Resulta exagerado duplicar el nmero de tipos de variables, por culpa de los apuntadores; veamos un artificio que nos da una solucin
corta y elegante. Tenemos una definicin:
int n;
int puntero ptr = &n;
Si aplicamos el operador * a ptr, podemos escribir:
int n;
int *ptr = &n;
// *ptr es el valor apuntado por ptr
Se lee as:
El valor apuntado por ptr es de tipo int
int *ptr = &n;
valor de ptr = direccin de n
Tambin se puede definir y asignar por separado en dos instrucciones:
int n = 65;
int *ptr;
ptr = &n;
// ptr toma como valor la direccin de n
O definir todo junto:
int n = 65, *ptr = &n;
Se representa as:
memoria

ptr
0x7ff...c
0x7ff...0

n
65
0x7ff...c

Para otros tipos de dato, se procede en modo anlogo:


float df = 21.1, *ptrf = &df;
Atento a los detalles
1) Para qu tanto artificio? Respuesta: Al momento de programacin trabajamos con variables, lo cual es esttico: el programador
prev (adivina) tamaos de arreglos (bloques) de datos; si se queda corto, el programa funciona mal o no funciona, si se alarga,
desperdicia memoria cara. El uso de apuntadores permite aplicar la lgica a la parte fsica en tiempo de ejecucin, lo cual es
dinmico; por ejemplo si define un puntero a un bloque de 20 elementos y se necesitan 40 ms, puede redimensionarlo a 60 con
suma facilidad; esto se aplica mucho para cadenas de caracteres; esto no se puede hacer usando arreglos. Adicionalmente, los
punteros reflejan en modo directo la naturaleza lineal de la memoria RAM.
2) Al asignar valor a ptr:
int n, m, *ptr;
ptr = &n;
ptr = &m;
ptr = NULL;
ptr = 0x7ff...c
n = 0x6ff...c;
*ptr = 0x7ff...c;

// ptr apunta a n (al primer byte)


// ptr apunta a m (otra variable)
// ptr no apunta a nada
// No compila porque no podemos manejar directamente a la memoria, esta es tarea del sistema operativo.
// No compila , adems n es de tipo entero, no hexadecimal
// No compila , adems *ptr es de tipo entero.

3) & y * son opuestos, pero no por completo, atento:


Son opuestos para variables apuntadoras : *&ptr = ptr = 0x7ff...c;
No Opuestos para variables no apuntadoras : *&n = n = 65;

&*ptr = ptr = 0x7ff...c

pero &*n, no compila, debido a que *n funciona solo si n fuera una


posicin de memoria, y no lo es.

4) Un apuntador tiene tres atributos:


tipo de dato al que apuntar : int, char, etc. (un solo tipo).
tipo
: apuntador, ocupa 8 bytes, el formato de impresin es %p: printf(%p, ptr);
valor
: direccin de la variable o bloque apuntado (en este caso) = 0x7ff...c
tipo dato, tipo, valor
int n = 65, *ptr = &n;
PGINA: 2

Lenguaje C
5) Variables y valores del ejemplo:
n = 65
ptr = 0x7ff...c
&n = 0x7ff...c
&ptr = 0x7ff...0
*n error, n no es posicin de memoria *ptr = 65
6) Mientras ptr apunte a n, se cumplen las siguientes relaciones:
Variables
Relacin
Ejemplo
&n y ptr

n y *ptr

Equivalentes

Leer valor de n:
scanf(%d, &n);
scanf(%d, ptr);

No equivalentes

ptr = &m;
&n = algo;

Equivalentes

Escribir valor de n
printf(%d, n);
printf(%d, *ptr);

// apunta a otra variable


// error: no se asigna posicin de memoria a una variable

Asignar valor cualquiera a n:


n = 65;
*ptr = 65;
n += 2;
*ptr += 2;
7) Un solo operador * representa a dos operaciones distintas:
* : Indireccin
* : Multiplicacin
El operador de indireccin * tiene mayor prioridad que el operador de multiplicacin *, ejemplo:
int n=2, *ptr= &n, b;
b = *ptr * 2; // es equivalente a: b = *ptr*2; b = 2 * *ptr; b = 2**ptr; b = 2 * * ptr; (no importa la cantidad de espacios)
No abuse de la escritura confusa, de ser necesario use parntesis para aclararla. Ms adelante completaremos las reglas de
priorizacin.
Ejemplo: Una variable puede ser apuntada por varios apuntadores:
#include<stdio.h>
void main(void){
int n=2 , *p1= &n, *p2= &n, m = 8;
// declaracin y asignacin de valores
if(p1==p2) printf("%d %d\n", *p1, *p2);
// Igualdad de apuntadores
}
Salida:
2 2
Diagrama de variables:
p1
0x7ff...a

p2
0x7ff...a

n
2
0x7ff...a

m
8

Observaciones:
El valor de n puede cambiar de 3 modos:
n = 4;
*p1 = 4;
*p2 = 4;
Un puntero apunta a 0 o 1 variable; pero puede cambiar de variable apuntada:
p1 = &m;
// y deja de apuntar a n
Apuntador constante
int a=10, b=20;
int * const p = &a; // p apunta solo a la variable a.
*p = 15;
// Correcto: asigna 15 a a, el valor apuntado es variable.
p=&b;
// ERROR: El valor de p es constante
p
a
0x7ff...a
15
0x7ff...a

b
20

PGINA: 3

Lenguaje C
Ya utilizamos apuntadores en funciones para pasar valores por referencia:
miFun(&n);
// el valor de n cambiar a 3.
Llama a:
void miFun(int *n) {*n= 3;}
Pero el uso ms frecuente es para apuntar a bloques de datos, como veremos a continuacin.

Arreglo de una dimensin


Un arreglo es un bloque de n datos del mismo tipo almacenados en modo consecutivo, ejemplo:
int arr[3] = {10, 20, 30};
arr
10 20 30
0x7ff...a
Indices:
0
1 2
Un arreglo de una dimensin es ideal para ser controlado por un apuntador; de hecho, un arreglo arr se comporta como un puntero
constante que apunta a su primer elemento:
arr == &arr[0]
// arr apunta a su primer elemento.
*arr == arr[0]
// 10
En modo general se cumple:
Notacin vectorial
Notacin de punteros

Valor

arr;

0x7ff...a

arr[0];

*(arr+0); *arr;

10

arr[1];

*(arr+1);

20

arr[2];

*(arr+2);

30

arr[1] = 80;

*(arr+1) = 80;

80

n = fun(arr, 3);

n = fun(arr, 3);

Llama a la funcin fun()

int fun(int arr[ ], int n){


arr[0] = 2;
arr[1] = 3;
*(arr+2) = 4;
}

int fun(int *arr, int n) {


*arr = 2;
*(arr+1) = 3;
arr[2] = 4;
}

Define a la funcin fun()

Ejemplo: Imprimir los elementos de un arreglo utilizando notacin vectorial y de apuntadores:


Programa 06_01a.c:
#include<stdio.h>
void main(void){
int arr[3] = {6, 5 , 4}, i;
for(i=2; i>=0; i--) printf("%d %d\n", arr[i], *(arr+i)); // Notacin de apuntadores
}
Salida:
4 4
5 5
6 6
El mismo ejemplo llamando a una funcin
Programa 06_01b.c:
#include<stdio.h>
void imprimir(int arr[], int n);
void main(void){
int arr[3] = {6, 5 , 4};
imprimir(arr, 3);
}
void imprimir(int arr[ ], int n) {
int i;
for(i=n; i>=0; i--) printf("%d %d\n", arr[i], *(arr+i));
}
Salida: la misma del problema anterior

// Notacin de apuntadores

PGINA: 4

Lenguaje C

Apuntador a arreglo de una dimensin


Un arreglo se comporta como un apuntador constante, lo cual imposibilita que cambie la posicin apuntada (a su primer elemento), un
apuntador que apunta al arreglo no tendra esta limitante, ejemplo:
int arr[3] = {10, 20 ,30}, arr1[4], *ptr;
ptr = arr;
// no es necesario & ya que arr es un puntero (constante)
ptr = arr1;
arr = arr1;
// Error de compilacin
memoria

ptr
0x7ff...0
0x7fa...b

arr
10 20
0x7ff...0

arr1
30

Aritmtica de punteros
Dada la naturaleza de un puntero -apunta a una direccin sobre una lnea-, el puntero se puede desplazar a la derecha-izquierda,
mediante sumas y restas:
ptr = ptr + 1;
// ptr apunta a la siguiente posicin de tipo int: avanza 4 bytes: 0x7ff...4
// si ptr apuntara a un tipo long, sumar 8 bytes, para char sumar 1 byte; etc.
ptr = ptr + n;
// equivalente a ptr += n;
ptr = ptr - n;
// equivalente a ptr -= n;
ptr + 2*3+1;
// = pptr + 7; apunta 7 posiciones de bytes, es decir 7*4 bytes ms adelante.
Se permite la resta de dos punteros:
int nn[10], *ptr1, *ptr2, n;
ptr1 = nn;
// equivalente a: ptr1 = &nn[0];
// apunta a nn[0].
ptr2 = &nn[2];
// apunta a nn[2].
n = ptr2 ptr1;
// diferencia en posiciones enteras = 2.
No se permiten otro tipo de operaciones
ptr = ptr * 2;
// Error: No se admiten multiplicaciones de valores de memoria
ptr1 = ptr1 + ptr2;
// Error
Mientras ptr apunte a arr:
int arr[3] = {10, 20, 30}, *ptr = arr;
Son equivalentes (sinnimos) por completo
arr[i] = = ptr[i];
*(arr+i) = = *(ptr+i);
Pre y postoperadores, funcionan como siempre:
arr++;
// error porque arr es puntero constante
ptr++;
// aumenta 1 a ptr;
printf("%p\n", ptr++);
// printf("%p\n", ptr); ptr++;
printf("%p\n", (ptr+1)++);
// error de compilacin, no se puede postoperar a una expresin (ptr+1)
*arr++;
*ptr++;
printf("%d\n", *ptr++);
printf("%d\n",*(ptr++));
printf("%d\n", *(ptr+1)++);

// error porque arr es puntero constante

++arr;
++ptr;
printf("%p\n", ++ptr);
printf("%p\n", ++(ptr+1));

// error porque arr es puntero constante


// aumenta 1 a ptr;
// ++ptr; printf("%p\n", ptr);
// error de compilacin

*arr++;
++*ptr;
printf("%d\n", ++*ptr);
printf("%d\n",++(*ptr));
printf("%d\n", ++*(ptr+1));

// error porque arr es puntero constante


// aumenta 1 a *ptr;
// aumenta 1 a *ptr;
printf("%d\n", *ptr) ;
// aumenta 1 a *ptr;
printf("%d\n", *ptr) ;
// aumenta 1 a *(ptr+1); printf("%d\n", *(ptr+1));

// printf("%d\n", *ptr); ptr++;


// printf("%d\n", *ptr); ptr++;
// error de compilacin

PGINA: 5

Lenguaje C

Arreglo de dos dimensiones


Podemos visualizar con facilidad una matriz, basta representarla en un papel (dos dimensiones):
2 4 6 7
8 10 12 14
La memoria del computador es de una sola dimensin, no queda otra alternativa que adaptar las dos dimensiones a una:
int arr[2][4] = {2, 4, 6, 7, 8, 10, 12, 14};
Posicin[]:
Posicin[ ][ ]:

arr[0][0]

arr[0][1]

arr[0][2]

arr[0][3]

arr[1][0]

arr[1][1]

arr[1][2] arr[1][3]

Valores

2
4
6
7
8
10
12
0X7234... = posicin fsica
Analizando las posiciones lineales y matriciales anteriores, deducimos que:
arr[i][j] ocupa la posicin i*4+j en la memoria
En general. para un arreglo arr[m][n], el elemento arr[i][j] ocupa la posicin: i*n+j en la memoria.

14

Los arreglos de dos dimensiones nos ayudan pero presentan tres limitaciones:
El lenguaje C los concibe como un arreglo de arreglos
arr[0]: fila 0
arr[1]: fila 1

// arr[0][0] 2
// arr[1][0] 8

arr[0][1] 4
arr[1][1] 10

arr[0][2] 6
arr[1][2] 12

arr[0][3] 7
arr[1][3] 14

Esta solucin no es unidimensional y presentar inconvenientes ms adelante.

Se debe estimar el nmero de fila y columnas por exceso, lo cual es un gran desperdicio de memoria, por otra parte si nos
excedemos, no hay advertencia de ello, y nos esperan errores y/o el aborto del programa.

Al pasar arreglos a funciones se pierde flexibilizad a partir de la segunda dimensin.

Afortunadamente, se resuelven los tres problemas anteriores en modo ptimo: Trabajar con punteros, asignar memoria dinmicamente y
controlar el nmero de elementos en cada dimensin; lo cual haremos en dos captulos ms adelante; por el momento hagamos una
aproximacin conceptual trabajando con arreglos y apuntadores:

Apuntador a arreglo de dos dimensiones


int arr[2][3] = {2, 4, 6, 8, 10, 12}, *ptr = arr;
Posiciones:
ptr
0x7234

0
arr[0][0]
2
0x7234...

// no se requiere &. ptr y arr apuntan a la misma direccin.


1
arr[0][1]
4

2
arr[0][2]
6

3
arr[1][0]
8

4
arr[1][1]
10

5
arr[1][2]
12

arr[i][j] es equivalente a *(ptr+ i*3+j)


En general para: int arr[m][n];
arr[i][j] ocupa la posicin: i*n+j.
arr[i][j] es equivalente a *(ptr+ i*n+j)
La notacin de punteros es engorrosa para referirse a los elementos de un arreglo; pero su uso permite parametrizar las dimensiones.

Paso de argumentos a funcin


Paso de una variable
Ejemplo: Calcular la mitad de un nmero
Programa 06_02a.c:
Paso de variable por valor
#include <stdio.h>
void mitad(int n);
// prototipo
void main(void){
int n = 2;
mitad(n);
// llamando
printf("n = %d\n", n);

Paso de variable por referencia

Paso de puntero a variable

#include <stdio.h>
void mitad(int *n);
// prototipo
void main(void){
int n = 2;
mitad(&n);
// llamando
printf("n = %d\n", n);

#include <stdio.h>
void mitad(int *pn); // prototipo
void main(void){
int n = 2, *pn = &n;
mitad(pn);
// llamando
printf("n = %d\n", n);
PGINA: 6

Lenguaje C
}
void mitad(int n){
n /=2;
}

}
void mitad(int *n){
*n /=2;
}

// funcin

Salida: n = 2

// funcin

Salida: n = 1;

}
void mitad(int *pn){
*pn /=2;
}

// funcin

Salida: n = 1;

Paso de puntero a arreglo


Ejemplo: Calcular la mitad de los elementos
Programa 06_02b.c:
Usando punteros

Sin usar punteros

1 dimensin

2 dimensiones

#include <stdio.h>
void mitad(int *parr, int n);
void main(void){
int arr[4] = {1, 2, 3, 4}, *parr = arr, i;
mitad(parr, 4);
for(i=0; i < 4; i++)
printf("%d\t", arr[i]);
}
void mitad(int *parr, int n){
int i;
for(i=0; i < n; i++) *(parr+i) /=2;
}

01
02
03
04
05
06
07
08
09
10
11
12
13

#include <stdio.h>
void mitad(int *parr, int m, int n);
void main(void){
int arr[2][2] = {1, 2, 3, 4}, *parr = arr, i, j;
mitad(parr, 2, 2);
for(i=0; i < 2; i++)
for(j=0; j < 2; j++) printf("%d\t", arr[i][j]);
}
void mitad(int *parr, int m, int n){
int i, j;
for(i=0; i < m; i++)
for(j=0; j < n; j++) *(parr+i*n+j) /=2;
}

#include <stdio.h>
void mitad(int parr[][2], int m, int n);
void main(void){
int arr[2][2] = {1, 2, 3, 4}, i, j;
mitad(arr, 2, 2);
for(i=0; i < 2; i++)
for(j=0; j < 2; j++) printf("%d\t", arr[i][j]);
}
void mitad(int arr[][2], int m, int n){
int i, j;
for(i=0; i < m; i++)
for(j=0; j < n; j++) arr[i][j] /=2;
}

Salida: 0 1 1 2
Salida: 0 1 1 2
Salida: 0 1 1 2
Nota: 1
Nota: 2
Nota: 3
Notas:
1: El programa es paramtrico en una dimensin.
2: El programa es paramtrico en las dos dimensiones; pero compila con un warning (advertencia) por tipo de apuntador en la lnea 04,
debido a que un apuntador de tipo int (lineal) apunta a una matriz (arreglo de arreglos) de tipo int; pero ejecuta bien (por que
controlamos las dimensiones). El programa compilar limpiamente cuando usemos solo punteros y memoria dinmica, que ser dos
captulos ms adelante.
3: El programa es paramtrico solo en la primera dimensin, ms no en la segunda.
Ejercicio: Definir un arreglo, calcular el mnimo, la suma y la media
Veamos dos temas que usaremos ms adelante.

Arreglo de apuntadores
Un puntero es una variable como cualquier otra, por lo tanto podemos tener arreglos de punteros, ejemplo:
int *ptr[4], n = 6;
ptr[1] = &n;
*ptr[1];
// = 6
ptr
Posiciones

0xff..c
1
2

n
6
0xff..c

Apuntador a apuntador
Un puntero es una variable como cualquier otra, por lo tanto podemos definir un puntero a puntero:
Sintaxis: tipo **nombreApuntador, ejemplo:
int a = 3, *b = &a, **c = &b;
c
0x7234..
0x65734..
printf("%d\n", a);
printf("%d\n", *b);

b
0x8174..
0x7234..

a
3
0x8174..

// resultado: 3
// resultado: 3
PGINA: 7

Lenguaje C
printf("%d\n", **c);
a = 4;

// resultado: 3
// es equivalente a: *b = 4; **c = 4;

Atento: el operador * tiene diferentes usos:


Uso
*
Para indicar puntero: *p1
**
Para indicar puntero a puntero: int **p2
*
Operador de multiplicacin: a * b
Expresin 2 ***p2; // es vlida y el compilador la reconoce, pero ud. se puede confundir, no abuse, use parntesis para separar.
Ejemplo: Definir, asignar valores y representar la memoria fsica:
int arr[4] = {15, 13, 11, 9}, *ptr1, **ptr2;
ptr1 = arr; ptr2 = *ptr1;
La implantacin en memoria sera:
ptr2
ptr1
0x7234..
0x8174..
0x65734..
0x7234..

arr
15
0x8174..

13

11

int arr[4] = {15, 13, 11, 9}, *ptr1, **ptr2;


ptr1 = arr; ptr2 = &ptr1;
printf("%d\n", *arr);
// resultado: 15
printf("%d\n", *ptr1);
// resultado: 15
printf("%d\n", **ptr2);
// resultado: 15

Reglas de priorizacin de los modificadores *, ( ) y [ ]


1) La cercana (derecha o izquierda) al puntero
2) ( ) y [ ] tienen mayor prioridad que *
3) Use parntesis para dar mayor prioridad, como en: (3 + 4) * 2
Ejemplo:
int *ptr[2][3];
* y [2] son adyacentes a ptr, y tienen mayor prioridad que [3] (regla 1):
(*ptr[2])[3]
[2] tiene preferencia sobre * (regla 2)
*(ptr es un arreglo de 2 elementos)[3]
[3] tiene preferencia sobre * (regla 2)
*(ptr es un arreglo de [2][3] elementos) ptr es un arreglo de [2][3] elementos de punteros a int
ptr

m
2

n
6

Programa 06_03.c:
#include<stdio.h>
void main(void){
int *ptr[2][3], j= 2, m=6, n=4;
ptr[0][0] = &j;
ptr[0][1] = &m;
ptr[0][2] = &n;
printf("%d\n", *ptr[0][0]);
printf("%d\n", *ptr[0][1]);
printf("%d\n", *ptr[0][2]);
}
Salida:
2
6
4
ejemplo:
int (*ptr)[2][3];
(*ptr)
Es un puntero
(*ptr)[2][3] Es un puntero a arreglos [2][3] de tipo int
PGINA: 8

Lenguaje C
Ejemplo:
int aa[2][3] = {1,2,3,4,5,6};
int *ptr = aa;
ptr

aa
1

Estas reglas se aplican tambin para funciones:


int *miFun();
// miFun() retorna un puntero a int
int miFun(int *ptr);
// El parmetro de miFun() es de tipo puntero a int

Apuntador a void
La palabra reservada void (se pronuncia void en ingls y significa vaco, nulo, vacante, ...) se utiliza para crear un puntero sin especificar
el tipo de dato al que apuntar:
int
in=1;
double db=2.4;
void *pvoid; // un apuntador a void puede apuntar a cualquier tipo de dato:
pvoid = &in;
pvoid = &db;
pin

int
*pin = (int *)pvoid;
double *pdb = (double *)pvoid;
pdb

pvoid

printf("%d\n", *pin);
printf("%lf\n", *pdb);
in

// = 1
// = 2.4

db
1

2.4

Ejemplo: La funcin free( ) usa este parmetro:


void free(void *ptr);
// free acepta un puntero a cualquier tipo de dato y le quita la referencia, lo hace NULL.

Ventajas, desventajas y usos de apuntadores


Ventajas
Desventajas
Usos

Permiten adaptarse a la memoria lineal del computador.


Ahorran memoria, los arreglos desperdician mucha memoria.
Permiten parametrizar la entrada a funciones con arreglos multidimensionales.
La notacin de punteros es un poco ms compleja.
Pueden ser un poco ms lentos de ejecutar que con arreglos simples. Ya que esta parte es optimizada por C, mientras
que los punteros los maneja el programador.
Se usa preferentemente para manejar bloques de memoria, recuerde las limitaciones para pasar arreglos de ms de
una dimensin a funciones, ahora eso no ser un problema.
No se suele apuntar a variables simples

Ejemplo: Dado un puntero como, float *fp. Verifique que al sumar n a fp (fp += n); la direccin apuntada por fp aumenta a:
n*sizeof(float).
Programa 06_04.c:
#include<stdio.h>
void main(void){
float f, *fp = &f;
long int d1, d2;
int n=2;
printf("\nPrimera direccin apuntada: %p (en hexadecimal)\n", fp);
d1 = (long int)fp;
// primera direccin apuntada
fp +=n;
d2 = (long int)fp;
// segunda direccin apuntada
printf("Segunda direccin apuntada: %p (fp + 2)\n", fp);
printf("
--------------\n");
printf("Aumento de direccin : %lu\n", d2 - d1);
printf("n*sizeof(float) = %d * %lu = : %lu\n", n, sizeof(float), n*sizeof(float));
}
Salida:
Primera direccin apuntada : 0x7fff329c5ee0 (en hexadecimal)
Segunda direccin apuntada: 0x7fff329c5ee8 (fp + 2)
------------------Aumento de direccin
:
8
PGINA: 9

Lenguaje C
n*sizeof(float) = 2 * 4 =

Ejercicios:
1) Para un arreglo tridimensional, por ejemplo:
int a[2][3][2] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12} ;
Que posicin lineal ocupar a[i][j][k]?
2) Una matriz p[4][12] representa una produccin de los 12 meses en 4 aos. Lea la matriz y use punteros para calcular el promedio de
produccin en cada ao y en los 12 meses:
Aos
1
2
3
4
Promedio:
xx
xx
xx
xx

Promedio:

Meses
1
2
xx
xx

3
xx

4
xx

12
xx

PGINA: 10

Potrebbero piacerti anche