PUNTEROS - ING.KARINA ESQUIVEL · 2013-06-26 · 1. Reservamos memoria para almacenar dim elementos...

24
2013 UNAN – LEON Departamento de Computación Autor: Ing. Juan Carlos Antón Soto Asignatura: Programación Estructurada PUNTEROS

Transcript of PUNTEROS - ING.KARINA ESQUIVEL · 2013-06-26 · 1. Reservamos memoria para almacenar dim elementos...

2013

UNAN – LEON

Departamento de Computación

Autor:

Ing. Juan Carlos Antón Soto

Asignatura:

Programación Estructurada

PUNTEROS

PUNTEROS

Introducción

Los punteros son una de las más potentes características de C, pero a la vez uno de

sus mayores peligros. Los punteros permiten acceder directamente a cualquier parte de la

memoria. Esto da a los programas C una gran potencia. Sin embargo son una fuente

ilimitada de errores. Un error usando un puntero puede bloquear el sistema y a veces

puede ser difícil detectarlo.

Un puntero puede apuntar a un objeto de cualquier tipo, incluyendo estructuras,

funciones, etc. Los punteros se pueden utilizar para crear y manipular estructuras de

datos, para asignar memoria dinámicamente y para proveer el paso de argumentos por

referencia en las llamadas a funciones.

Direcciones de variables

¿Qué pasa cuando se declara una variable?

Al declarar una variable se le dice a la computadora que reserve una parte de la memoria

para almacenarla. Cada vez que se ejecute el programa, la variable se almacenará en un

sitio diferente, eso no se puede controlar, depende de la memoria disponible.

Dependiendo del tipo de variable que se declare la computadora reservará más o menos

memoria. Por ejemplo si se declara un char, la computadora reserva 1 byte (8 bits).

Cuando finaliza el programa todo el espacio reservado queda libre.

1

PUNTEROS

Existe una forma de saber qué direcciones ha reservado la computadora. Se trata de usar

el operador & (operador de dirección). Por ejemplo: Se declara la variable 'a' y se obtiene

su valor y dirección.

#include <stdio.h>

void main()

{

int a;

a = 10;

printf( "Dirección de a = %p, valor de a = %d\n", &a, a );

}

Para mostrar la dirección de la variable usamos %p en lugar de %d, sirve para escribir

direcciones de punteros y variables. El valor se muestra en hexadecimal.

No hay que confundir el valor de la variable con la dirección donde está almacenada la

variable. La variable 'a' está almacenada en un lugar determinado de la memoria, ese lugar

no cambia mientras se ejecuta el programa. El valor de la variable puede cambiar a lo largo

del programa. Ese valor está almacenado en la dirección de la variable. El nombre de la

variable es equivalente a poner un nombre a una zona de la memoria. Cuando en el

programa se escribe 'a', en realidad se dice, "el valor que está almacenado en la dirección

de memoria de 'a'".

Para entender mejor lo anterior suponga que se tiene el dibujo siguiente:

2

PUNTEROS

En el dibujo se tiene una representación de lo que sería la memoria de la computadora.

Cada casilla representa un byte de la memoria. Y cada número es su dirección de memoria.

La primera casilla es la posición 00001 de la memoria. La segunda casilla la posición 00002

y así sucesivamente.

Suponga que se declara una variable char: char numero = 43. La computadora guardaría

por ejemplo la posición 00003 para esta variable. Esta posición de la memoria queda

reservada y ya no la puede usar nadie más. Además esta posición a partir de ahora se

llama numero. Como se le ha dado el valor 43 a numero, el valor 43 se almacena en la

posición 00003.

Si se escribe el siguiente programa:

#include <stdio.h>

void main()

{

int numero;

numero = 43;

printf( "Dirección de numero = %p, valor de numero = %d\n", &numero, numero );

}

El resultado sería:

Dirección de numero = 00003, valor de numero = 43

3

PUNTEROS

¿Qué es un puntero?

Un puntero es una variable un tanto especial. Con un puntero se puede almacenar

direcciones de memoria, es decir que se puede tener guardada la dirección de una

variable.

Cuando se declara un puntero se debe especificar el tipo de dato cuya dirección

almacenará. En el siguiente ejemplo se quiere almacenar la dirección de una variable char.

Así que para declarar el puntero punt debemos hacer:

char *punt;

El * (asterisco) sirve para indicar que se trata de un puntero, debe ir justo antes del

nombre de la variable, sin espacios. En la variable punt sólo se pueden guardar direcciones

de memoria, no se pueden guardar datos. Observe el ejemplo anterior un poco ampliado

para ver cómo funciona un puntero:

#include <stdio.h>

void main()

{

int numero;

int *punt;

numero = 43;

punt = &numero;

printf( "Dirección de numero = %p, valor de numero = %d\n", &numero, numero );

}

Véase el ejemplo anterior línea a línea:

En la primera int numero; se reserva memoria para numero (suponga que queda como

antes, posición 00003). Por ahora numero no tiene ningún valor.

Siguiente línea: int *punt;. Se reserva una posición de memoria para almacenar el

puntero. Lo normal es que según se declaran variables se guarden en posiciones

contiguas. De modo que quedaría en la posición 00004. Por ahora punt no tiene ningún

valor, es decir, no apunta a ninguna variable. Esto es lo que tenemos por ahora:

4

PUNTEROS

Tercera línea: numero = 43;. Se ha dado el valor 43 a numero. Se almacena 43 en la

dirección 00003, que es la de numero.

Cuarta línea: punt = &numero;. Se da un valor a punt. El valor que le damos es la

dirección de numero (ya se ha visto que & devuelve la dirección de una variable). Así

que punt tendrá como valor la dirección de numero, 00003. Por lo tanto ya se tiene:

Cuando un puntero tiene la dirección de una variable se dice que ese puntero apunta a esa

variable.

NOTA: La declaración de un puntero depende del tipo de dato al que queramos apuntar.

En general la declaración es:

tipo_de_dato *nombre_del_puntero;

Si en vez de querer apuntar a una variable tipo char como en el ejemplo hubiese sido de

tipo int:

int *punt;

¿Para qué sirve un puntero? ¿Cómo se usa?

Los punteros tienen muchas utilidades, por ejemplo permiten pasar argumentos (o

parámetros) a una función y modificarlos. También permiten el manejo de cadenas y de

arrays. Otro uso importante es que permiten acceder directamente a la pantalla, al

teclado y a todos los componentes de la computadora.

Pero si sólo sirvieran para almacenar direcciones de memoria no servirían para mucho.

Deben dejar también la posibilidad de acceder a esas posiciones de memoria. Para acceder

a ellas se usa el operador *.

5

PUNTEROS

#include <stdio.h>

void main()

{

int numero;

int *punt;

numero = 43;

punt = &numero;

printf( "Dirección de numero = %p, valor de numero = %d\n", &numero, *punt );

}

Si se observa los cambios con respecto al ejemplo anterior, se ve que para acceder al

valor de numero se usa *punt en vez de numero. Esto es así porque punt apunta a numero y

*punt permite acceder al valor al que apunta punt.

Ahora se ha cambiado el valor de numero a través de *punt.

#include <stdio.h>

void main()

{

int numero;

int *punt;

numero = 43;

punt = &numero;

*punt = 30;

printf( "Dirección de numero = %p, valor de numero = %i\n", &numero, numero );

}

En resumen, usando punt se puede apuntar a una variable y con *punt se cambia el

contenido de esa variable.

Un puntero no sólo sirve para apuntar a una variable, también sirve para apuntar a una

dirección de memoria determinada.

Usando punteros en una comparación

Vea el siguiente ejemplo. Se quiere comprobar si dos variables son iguales usando

punteros:

6

PUNTEROS

#include <stdio.h>

void main()

{

int a, b;

int *punt1, *punt2;

a = 5; b = 5;

punt1 = &a; punt2 = &b;

if ( punt1 == punt2 )

printf( "Son iguales\n" );

}

Se podría pensar que el if se cumple y se mostraría el mensaje “Son iguales” en pantalla.

Pues no es así, el programa es erróneo. Es cierto que a y b son iguales. También es cierto

que punt1 apunta a 'a' y punt2 a 'b'. Lo que se quería comprobar era si a y b son iguales.

Sin embargo con la condición se está comprobando si punt1 apunta al mismo sitio que

punt2, se está comparando las direcciones donde apuntan. Por supuesto a y b están en

distinto sitio en la memoria así que la condición es falsa. Para que el programa funcionara

deberíamos usar los asteriscos:

#include <stdio.h>

void main()

{

int a, b;

int *punt1, *punt2;

a = 5; b = 5;

punt1 = &a; punt2 = &b;

if ( *punt1 == *punt2 )

printf( "Son iguales\n" );

}

Ahora sí. Se está comparando el contenido de las variables a las que apuntan punt1 y

punt2. Se debe tener mucho cuidado con esto porque es un error que se da con mucha

facilidad.

Ahora se cambia un poco el ejemplo. Ahora 'b' no existe y punt1 y punt2 apuntan a 'a'. La

condición se cumplirá porque apuntan al mismo sitio.

7

PUNTEROS

#include <stdio.h>

void main()

{

int a;

int *punt1, *punt2;

a = 5;

punt1 = &a; punt2 = &a;

if ( punt1 == punt2 )

printf( "punt1 y punt2 apuntan al mismo sitio\n" );

}

Operaciones con punteros

Operación de asignación =

A un puntero se le puede asignar una dirección de memoria concreta, la dirección de

una variable o el contenido de otro puntero.

Una dirección de memoria concreta:

int *ptr;

...

ptr = 0x1F3CE00A;

...

La dirección de una variable del tipo al que apunta el puntero: char c;

char *ptr;

...

ptr = &c;

Otro puntero del mismo tipo: char c;

char *ptr1;

char *ptr2;

ptr1 = &c;

ptr2 = ptr1;

8

PUNTEROS

Ejemplo

Programa que suma un valor a una variable a través de un puntero

#include <stdio.h>

void main()

{

int a, *p;

a=5;

printf("\n\nEl valor inicial de a = %d y su dirección de memoria es : %p\n", a, &a);

p=&a;

printf("\np = &a\n\np = %p y *p = %d", p, *p);

*p+=7;

printf("\n\nEl contenido de *p se suma con el valor 7\n\n");

printf("\nEl valor final de la variable a = %d y el contenido de *p = %d\n\n", a,*p);

}

Su resultado es el siguiente:

El valor inicial de a = 5 y su dirección de memoria es 0012FF84

p = &a

p = 0012FF84 y *p = 5

El contenido de *p se suma con el valor 7

El valor final de la variable a = 12 y el contenido de *p = 12

PUNTERO NULO

Un puntero se puede inicializar como cualquier otra variable, aunque los únicos valores

significativos son NULL o la dirección de un objeto previamente definido.

NULL es una constante definida en el fichero stdio.h, cuando un puntero apunta a

NULL significa que apunta a la dirección 0 del sistema, y está a la espera de que se le

asigne una dirección válida. La siguiente sentencia no se debe realizar:

int *px = 103825;

Ya que el sistema es el encargado de asignar las direcciones y por lo tanto el usuario

no sabe acerca de la dirección 103825.

9

PUNTEROS

Errores comunes sobre punteros

Asignar punteros de distinto tipo

int a = 10;

int *ptri = NULL;

double x = 5.0;

double *ptrf = NULL;

ptri = &a;

ptrf = &x;

ptrf = ptri; // ERROR

Utilizar punteros no inicializados char *ptr;

*ptr = ‘a’; // ERROR

Asignar valores a un puntero y no a la variable a la que apunta int n;

int *ptr = &n;

ptr = 9; // ERROR

Intentar asignarle un valor al dato apuntado por un puntero cuando éste es NULL int *ptr = NULL;

*ptr = 9; // ERROR

Punteros y arrays

En C existe, entre punteros y arrays, una relación tal que, cualquier operación que se

pueda realizar mediante la indexación de un array, se puede realizar también con

punteros.

Cuando declaramos un vector

tipo identificador

[dim]

10

PUNTEROS

En realidad

1. Reservamos memoria para almacenar dim elementos de tipo tipo.

2. Creamos un puntero identificador que apunta a la primera posición de la

memoria reservada para almacenar los componentes del array.

Por tanto, el identificador del array es un puntero.

Operaciones aritméticas con punteros

A un puntero se le puede sumar o restar un entero.

int *p;

p++;

p--;

p = p + 3;

p = p – 3;

// declara p como un puntero a un entero

// hace que p apunte al siguiente entero

// hace que p apunte al entero anterior

// avanzar tres enteros

// retroceder tres enteros

Ejemplo de punteros con operaciones aritméticas

#include <stdio.h>

void main()

{

int a = 2, b = 5, c[] = {1,10,30,44}, i, j, *pa, *pb, *pc;

printf("\n\tValores iniciales\n");

printf("\t*****************\n");

printf("\t%s %5s %5s %5s\n", "a", "&a", "b", "&b");

printf("\t%d %5p %3d %5p\n\n", a, &a, b, &b);

for (i = 0, j = 0; i < 4; i++, j++)

printf("c[%d] = %3d &c[%d] = %p\n", i, c[i], j, &c[i]);

pa = &a; // pa apunta a la direccion de a

printf("\n\npa = &a pa = %p, *pa = %d\n\n",pa, *pa);

b = *pa + 1; // se le está sumando 1 al valor apuntado por pa y luego se asigna a b

printf("b = *pa + 1 b = %d\n\n",b);

pc = c; //pc apunta al arreglo c

printf("pc = c\n\n pc = %p\n\n", pc);

11

PUNTEROS

printf("el puntero pc se desplaza una posicion de memoria y asigna ese contenido a \'b\' \n ");

b = *(pc + 1); // pc se desplaza una posicion de memoria y asigna ese contenido a b

printf("\nb = *(pc + 1) b = %d\n", b);

printf("\npb = &b\n");

pb = &b;

printf("pb = %p , direccion de b = %p, b = %d\n\n",pb,&b,b);

printf("*pb = 0\n");

*pb = 0; // el contenido de pb es puesto a cero

printf("\n*pb += 2 La variable b indirectamente se incrementa en 2 unidades\n\n");

*pb += 2; // la variable b indirectamente se incrementa en dos unidades

printf("*pb = %d , b = %d\n\n",*pb,b);

printf("La variable b indirectamente se decrementa en 1 unidad\n\n");

(*pb) --; // La variable b indirectamente se decrementa en una unidad

printf("*pb = %d , b = %d\n\n",*pb,b);

}

El resultado sería el siguiente:

Valores iniciales

*****************

a &a b

2 0012ff50 5

&b

0012ff54

c[0] =

c[1] =

c[2] =

c[3] =

1

10

30

44

&c[0]: 0012ff58

&c[1]: 0012ff5c

&c[2]: 0012ff60

&c[3]: 0012ff64

pa = &a pa = 0012ff50, *pa = 2

b = *pa + 1 b = 3

pc = c

pc = 0012ff58

el puntero pc se desplaza una posicion de memoria y asigna ese contenido a \'b\' \n ");

b = *(pc + 1) b = 10

pb = &b

pb = 0012ff54 , direccion de b = 0012ff54, b = 10

*pb = 0

*pb += 2 La variable b indirectamente se incrementa en 2 unidades

*pb = 2 , b = 2

La variable b indirectamente se decrementa en 1 unidad

*pb = 1 , b = 1

12

PUNTEROS

Utilizando la aritmética de punteros nos desplazamos de unas posiciones de memoria

a otras. Pero ¿cómo acceder a los contenidos de esas posiciones utilizando notación de

punteros?

Empleando el operador *, indirección que nos da el contenido de la dirección de

memoria apuntada.

Ejemplo:

Analice el siguiente programa, escrito primeramente con matrices y a continuación

con punteros.

// versión utilizando una matriz unidimensional

#include <stdio.h>

void main()

{

int lista[ ] = {24,30,15,45,34};

int indice;

for(indice = 0; indice < 5; indice ++)

printf(“\t%d”,lista[indice]);

printf(“\n\n”);

}

El resultado sería el siguiente:

24

30

15

45

34

13

PUNTEROS

En este ejemplo se ha utilizado la indexación, expresión lista[indice], para acceder a

los elementos de la matriz lista. Cuando se interpreta ésta expresión se sabe que a partir

de la dirección de comienzo de la matriz, esto es, a partir de lista, tiene que avanzar

indice elementos para acceder al contenido del elemento especificado por ese índice.

//versión con punteros

#include <stdio.h>

void main()

{

int lista[ ] = {24,30,15,45,34};

int indice;

for(indice = 0; indice < 5; indice ++)

printf(“\t%d”,*(lista + indice));

}

Esta versión es idéntica a la anterior, excepto que la expresión para acceder a los

elementos del array es: *(lista + indice). Esto deja constancia de que lista es la dirección

de comienzo del array. Si a esta dirección le sumamos 1, dicho de otra manera si indice

vale 1, nos situamos en el siguiente entero de lista; esto es *(lista + 1) y lista[1]

representan el mismo valor.

Punteros a cadena de caracteres

Puesto que una cadena de caracteres es un array de caracteres, la forma de definir un

puntero a una cadena de caracteres es: char *cadena;

El identificador del array es la dirección de comienzo del array. Para saber dónde

termina la cadena, el compilador añade el carácter ‘\0’ (ASCII 0, NULL):

char *nombre = “PEPE PEREZ”;

14

PUNTEROS

Si se quiere recorrer la cadena con notación de punteros se hace lo siguiente:

#include <stdio.h>

void main ()

{

char *nombre = "PEPE PEREZ";

int i = 0;

do

{

printf("%c", *(nombre+i));

i++;

}while (*(nombre+i));

printf("\n");

}

Muchas funciones de C que trabajan con cadenas de caracteres, utilizan punteros y

devuelven como resultado un puntero. Por ejemplo, la función de C strchr() para localizar

un carácter en una cadena, devuelve un puntero al carácter buscado o un puntero nulo si el

carácter no se encuentra. Ejemplo:

#include <stdio.h>

#include <string.h>

int main()

{

const char *cadena = "FERROCARRIL";

char caracter1 = 'A';

char caracter2 = 'z';

if ( strchr( cadena, caracter1 ) != NULL )

printf( "\n\'%c\' se encuentra en %s\n\n", caracter1, cadena );

else

printf( "\n\'%c\' no se encontro en %s\n\n", caracter1, cadena );

if ( strchr( cadena, caracter2 ) != NULL )

printf( "\n\'%c\' se encontro en %s\n\n", caracter2, cadena );

else

printf( "\n\'%c\' no se encontro en %s\n\n", caracter2, cadena );

return 0;

}

15

PUNTEROS

El siguiente ejemplo copia una cadena de caracteres en otra, utilizando punteros.

#include <stdio.h>

void copia_cadena(char *p, char *q);

void main()

{

char cadena1[50], cadena2[50];

printf("Introducir cadena: ");

gets(cadena1);

copia_cadena(cadena2,cadena1); // copia la cadena1 en la cadena2

printf("\n\tLa cadena copiada es: %s\n\n",cadena2);

}

void copia_cadena(char *p, char *q)

{

while ((*p = *q) != '\0')

{

p ++;

q ++;

}

}

El resultado sería el siguiente:

// copia q en p

Introducir cadena:

Ingenieros en Sistemas de Información

La cadena copiada es: Ingenieros en Sistemas de Información

El bucle formado por la sentencia while, realiza las siguientes operaciones:

1. Toma el carácter contenido en la dirección dada por q y lo copia en la dirección dada

por p.

2. Ve si el contenido de p es el carácter nulo.

3. p pasa apuntar a la siguiente dirección, y lo mismo sucede con q. Si no se dio la

condición de terminación, el proceso se repite desde el inicio.

16

PUNTEROS

Matrices de punteros

Son matrices que contienen elementos de tipo puntero, es decir, cada elemento de la

matriz contiene una dirección en lugar de un dato de tipo primitivo.

Ejemplo:

#include <stdio.h>

void main()

{

int *p[5];

int b = 30;

p[0] = &b;

//matriz de 5 elementos (int *)

// variable de tipo int

// p[0] apunta al entero b

El resultado sería el siguiente:

El contenido de *p[0] = 30

printf (“\n\tEl contenido de *p[0] = %d\n\n”,*p[0]);

}

Un array de dos dimensiones y un array de punteros se pueden usar de forma

parecida, pero no son lo mismo. Ejemplo:

int a[5][5];

int *p[5];

//array bidimensional

//array de punteros

En el ejemplo anterior, el compilador reserva memoria para un array a de 25

elementos de tipo entero y para un array p de 5 elementos declarados como punteros a

objetos de tipo entero.

Si cada uno de los objetos apuntados por los elementos del array p es a su vez un

array de 5 elementos de tipo entero, la ocupación de memoria será la de los 5 elementos

de p más la de los 25 elementos de los 5 array de enteros.

El acceso a los elementos de la matriz p puede hacerse utilizando la notación de

punteros o utilizando la indexación igual que lo haríamos con a.

Por ejemplo para asignar valores a los elementos referenciados por la matriz p y

después visualizarlos sería de la siguiente forma:

17

PUNTEROS

#include <stdio.h>

#define F 5

#define C 5

void main()

{

int a[F][C] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25};

int *p[F], i, j;

//A cada posición del arreglo de punteros se le está asignando la dirección de memoria de cada

posición del arreglo bidimensional.

for (i = 0; i < F; i++)

p[i] = a[i];

printf("\n\n");

//Impresión de los elementos almacenados en el arreglo bidimensional a través del

//arreglo de punteros.

for (i = 0; i < F; i++)

{

for (j = 0; j < C; j++)

printf("%5d ", p[i][j]);

printf("\n\n");

}

}

El resultado sería el siguiente:

1

6

11

16

21

2 7 12 17 22

3 8 13 18 23

4 9 14 19 24

5 10 15 20 25

¿Cómo se aplica la notación de punteros o aritmética de punteros para desplazarse en

un array bidimensional?

18

Con subíndices Con punteros valor

p[0][0] *(*(p+0)+0) 1

p[0][1] *(*(p+0)+1) 2

p[0][2] *(*(p+0)+2) 3

p[0][3] *(*(p+0)+3) 4

.

.

.

p[4][4] *(*(p+4)+4) 25

PUNTEROS

Existe por tanto una equivalencia:

*p representa un puntero a la primera fila, con *(p+1)+j para las direcciones y

*(*p+1)+j) para los contenidos. El segundo subíndice actúa sobre la columna.

Si en x[10][20] se quiere acceder al elemento de la fila 3 y la columna 6, se hace

escribiendo x[2][5]. Con notación de punteros, es equivalente a *(*(x+2)+5), ya que x+2

es un puntero a la fila 3. Por tanto. El contenido de dicho puntero, *(x+2), es la fila 3. Si

se desplaza 5 posiciones en esa fila se llega a la posición *(x+2)+5, cuyo contenido es

*(*(x+2)+5). Ver dibujo:

19

PUNTEROS

Punteros a punteros

Para especificar que una variable es un puntero a un puntero, la sintaxis utilizada es la

siguiente:

Tipo **varpp;

Donde Tipo especifica el tipo del objeto apuntado después de una doble indirección

(puede ser cualquier tipo incluyendo tipos derivados) y varpp es el identificador de la

variable puntero a puntero.

Por ejemplo: int a, *p, **pp;

a = 10; //dato

p = &a; // puntero que apunta al dato

pp = &p; // puntero que apunta al puntero que a la vez apunta al

// dato

Se dice que p es una variable con un nivel de indirección, esto es, a través de p no se

accede directamente al dato, sino a la dirección que indica dónde está el dato. Haciendo

un razonamiento similar se dice que pp es una variable con dos niveles de indirección.

Ejemplo:

#include <stdio.h>

void main()

{

int a[3][3], *p[3], **q, i,j;

for (i = 0; i < 3; i++)

p[i] = a[i];

q =p;

for (i = 0; i < 3; i++)

{

for (j = 0; j < 3; j++)

{ printf("q[%d][%d] = ",i,j);

scanf("%d", &q[i][j]);

}

}

printf("\n\n");

for (i = 0; i < 3; i++)

20

PUNTEROS

{

for (j = 0; j < 3; j++)

printf("%5d ",q[i][j]);

printf("\n");

}

}

El nombre de un array de dos dimensiones no puede considerarse como un puntero a

puntero. La siguiente asignación daría un error.

int a[5][5];

int **p = a; //diferentes niveles de indirección

21

PUNTEROS

EJERCICIOS PROPUESTOS

PUNTEROS

1. Encuentre los errores en la siguiente declaración de punteros.

int x, *p;

char *b = “Cadena Larga”;

char *car = ‘C’;

x = 6;

p = x;

p = b;

2. Encuentre el error del siguiente programa y de una solución para poder ejecutarlo sin

ningún fallo.

#include <stdio.h>

int main()

{

int *a, b = 5;

*a = 5;

printf("*a = %d y b = %d\n\n", a, b);

}

3. En el siguiente código se accede a los elementos de una matriz. Acceder a los mismos

elementos a través de punteros.

#define N 4

#define M 5

int f, c;

float mt[N][M];

for (f = 0; f < N; f++)

{

for (c = 0; c < M; c++)

printf(“%f”,mt[N][M]);

printf(“\n\n”);

}

22

PUNTEROS

4. Escriba un programa que de un valor a una variable. Esta sea apuntada por un puntero y

sumarle 10 a través del puntero. Luego imprima el resultado.

5. Calcule la longitud de una cantidad de caracteres ingresada por el teclado y visualice las

letras que contiene.

6. Escriba un programa en C que cuente el número de veces que aparece un carácter en

una cadena de N caracteres.

7. Realice un programa que pida por teclado el tamaño de un arreglo y que almacene en él

números enteros aleatorios. Para recorrer el arreglo se pide utilizar punteros en lugar

de índices.

23