Subido por andymartiinez347

Explicación y practica de Punteros Universidad de el Salvador

Anuncio
UNIVERSIDAD DE EL SALVADOR
FACULTAD DE INGENIERIA Y ARQUITECTURA
ESCUELA DE INGENIERIA DE SISTEMAS INFORMATICOS
ESTRUCTURAS DE DATOS
GUIA DE LABORATORIO
PUNTEROS
Introducción:
Un puntero es una variable que contiene la dirección de un objeto ya sea otra variable, un vector,
estructura, etc . Cuando se declara un puntero éste contiene una dirección arbitraria, si leemos a
dónde apunta nos dará un valor indefinido y si se escribe en tal dirección estamos variando el
contenido de una posición de memoria. Los punteros son útiles para: modificar los argumentos
en las funciones, asignación dinámica de memoria y la optimización de uso de la misma.
La presente guía pretende ejemplificar el uso de los punteros en diferentes situaciones para una
mejor comprensión de su uso.
Objetivo:
Que el estudiante conozca y practique el uso de los punteros en C.
Ejemplo 1
Objetivo del programa: Mostrar el uso de los operadores básicos en la declaración de punteros
Empleando el direccionamiento y el operador de indirección.
#include <stdio.h>
#include <conio.h>
void main(void) {
int a;
int *punt; //declaración de puntero.
a=57; //inicialización de variable
punt=&a; //asignación de dirección al puntero.
clrscr();
printf("a = %d", a); //imprimo valor de variable
printf("\n&a = %x", &a); //imprimo dirección variable apuntada (en hexadecimal)
printf("\npunt = %x ", punt); //imprimo la dirección guardada (la de la variable apuntada)
printf("\n*punt = %d", *punt); //imprimo el contenido de la dirección apuntada.
printf("\ntama¤o puntero %d", sizeof(punt));
getch();
}
Ejemplo 2
Objetivo del programa: Manipular el contenido de variables de diferentes tipos de datos a
través de la aplicación de punteros.
#include <stdio.h>
#include <conio.h>
void main() {
char carac='A', *r;
int a=12,b=45, c;
ESTRUCTURAS DE DATOS
CICLO II
1
int *p, *q;
clrscr();
printf("Dirección de a=%p\n", &a);
printf("Dirección de b=%p\n", &b);
printf("a = %d b = %d\n", a, b);
printf("Dirección de caract = %p\n", &carac);
printf("carac = %c\n", carac);
printf("Valor ASCII de carac = %d\n", carac);
printf("Dirección de p = %p\n", &p);
printf("Dirección de q = %p\n", &q);
printf("Dirección de r = %p\n", &r);
p = &a;
q = &b;
r = &carac;
printf("El puntero p apunta a la dirección: %p\n", p);
printf("Y su contenido es: %d\n", *p);
printf("El puntero q apunta a la dirección: %p\n", q);
printf("Y su contenido es: %d\n", *q);
printf("El puntero r apunta a la dirección: %p\n", r);
printf("Y el contenido de *r es: %d\n", *r);
printf("Como caracter ASCII *r contiene: %c\n", *r);
getch();
}
Ejemplo 3
Objetivo del programa: Aplicar la notación de punteros para manipular un arreglo. Note que el
arreglo tiene una limitante relacionada a la cantidad de memoria
reservada.
#include <stdio.h>
#include <stdlib.h>
#include<conio.h>
#define MAXCOL 30
void main() {
int nfila, ncol, f, c,(*a)[MAXCOL];
clrscr();
puts("Intro n§ de filas:");
scanf("%d", &f);
puts("Introducir numero de columnas:");
scanf("%d", &c);
puts("Llenamos el array:");
for(nfila=0; nfila<f; nfila++)
for(ncol=0; ncol<c; ncol++) {
printf("(*(a+%d)+%d) = ", nfila, ncol);
scanf("%d", *(a+nfila)+ncol);
}
puts("Imprimimos el array:");
for(nfila=0; nfila<f; nfila++)
{
for(ncol=0; ncol<c; ncol++)
printf(" %d",*(*(a+nfila)+ncol));
puts("");
ESTRUCTURAS DE DATOS
CICLO II
2
}
getch();
}
Ejemplo 4
Objetivo del programa: Referenciar a un arreglo como un puntero a un grupo de arreglos
contiguos.
#include <stdio.h>
#include <conio.h>
void main() {
int x[2][3], fil, col;
clrscr();
puts("Llenamos el array");
for(fil=0; fil<2; fil++)
for(col=0; col<3; col++)
{
printf("x[%d][%d] = ", fil, col);
scanf("%d", &x[fil][col]);
}
printf("\nImprimimos usando un puntero a un grupo de arrays:\n");
printf("\nPRIMERA FILA:\n");
for(col=0; col<3; col++)
printf(" %d", (*x)[col]);
printf("\nSEGUNDA FILA:\n");
for(col=0; col<3; col++)
printf(" %d", (*(x+1))[col]);
getch();
}
Ejemplo 5
Objetivo del programa: Mostrar el acceso al contenido de un arreglo a través de la declaración
de un puntero hacia esa estructura.
#include <conio.h>
#include <stdio.h>
void main() {
int mat[] = {1,2,3,4}, *pmat, i;
clrscr();
printf("\Empleamos notación decimal\n");
printf("Hacemos que el puntero señale al primer elemento del array: pmat = mat");
pmat = mat;
//pmat=&mat[0]; //ES LO MISMO QUE pmat =mat
printf("\nComprobamos los valores: ");
printf("\nDirección de inicio del array: mat = %u", &mat[0]);
getch();
printf("\nDirección de pmat: &pmat = %u", &pmat);
ESTRUCTURAS DE DATOS
CICLO II
3
getch();
printf("\n Imprimimos las direcciones de memoria:\n");
for(i=0; i<4; i++)
{
printf("\n&mat[%u] = %u (pmat+%u) = %u ", i, &mat[i], i, (pmat+i));
printf(" mat[%u] = %u *(pmat+%u) = %u" , i, mat[i], i, *(pmat+i));
}
getch();
}
Ejemplo 6
Objetivo del programa: Declarar un puntero a una cadena de caracteres e imprimirlo carácter
a carácter hasta que detecta, en el bucle do...while el carácter nulo
de final de cadena ('\0')
#include <stdio.h>
#include <conio.h>
void main() {
char *nombre = "PEPE PEREZ";
int i=0;
clrscr();
do
printf("%c", *(nombre+i));
while(*(nombre+i++)); //postincremento de i, para cambiar VCB
puts(" "); //imprime blanco ,m s salto de l¡nea.
puts(nombre);
getch();
}
Ejemplo 7
Objetivo del programa: Manipular estructuras de memoria estáticas, empleando subíndices y
aritmética de punteros.
#include <stdio.h>
#include <conio.h>
void main() {
float mat[2][4] = {
{1.45, -2.35, -14.08, 17.3}, //primera fila
{20, 2.95, 0.082, 6.023} //segunda fila
};
int i, j;
clrscr();
puts("Imprimimos las direcciones de memoria y valores contenidos:");
puts("\nDireccción de memoria &mat[i][j] \t\tContenido mat[i][j]");
for(i=0;i<2; i++)
ESTRUCTURAS DE DATOS
CICLO II
4
for(j=0; j<4; j++)
printf("\n\t&mat[%d][%d] = %p \t\t\t mat[%d][%d] = %g", i\
,j,&mat[i][j], i,j, mat[i][j]);
getch();
printf("\n\nRepetimos los resultados empleando notación de punteros:\n");
getch();
puts("\nDireccción de memoria *(mat+i)+j \t\tContenido *(*(mat+i)+j)");
for(i=0;i<2; i++)
for(j=0; j<4;j++)
printf("\n\t(mat+%d)+%d = %p \t\t\t *(*(mat+%d)+%d) = %g", i,j, *(mat+i)+j, i,j,
*(*(mat+i)+j));
getch();
printf("\n\nVeamos algunos valores (sin escribir i cuando vale cero: ");
printf("\n*(*(mat)) = %g",*(*(mat)));
printf("\n*(*(mat)+1) = %g",*(*(mat)+1));
printf("\n*(*(mat+1)+1) = %g",*(*(mat+1)+1));
getch();
}
Ejemplo 8
Objetivo del programa: acceder a los datos de un arreglo bidimensional, empleando subíndices
y aritmética de punteros.
/* Imprime los valores de una matriz con punteros*/
#include "stdio.h"
#include "conio.h"
#define FILAS 3
#define COLUMNAS 2
void main() {
int i;
char mat[FILAS][COLUMNAS]= {{1,2},{3,4},{5,6}};
clrscr();
puts("Imprimimos como array:");
for(i=0; i<FILAS*COLUMNAS; i++)
printf("%d\n", (*mat)[i]);
puts("\nImprimimos utilizando punteros:");
for(i=0; i<FILAS*COLUMNAS; i++)
printf("%d\n", (**mat+i)); //------getch();
}
Ejemplo 9
Objetivo del programa: Emplear notación de punteros para manipular un arreglo
unidimensional de punteros
ESTRUCTURAS DE DATOS
CICLO II
5
// con notación de punteros tanto en la entrada como
//salida de datos.
#include "stdio.h"
#include "conio.h"
void main() {
int i,j;
int *p[4]; //array de punteros//
int **px=p; //px es un puntero a un puntero//
clrscr();
printf("Introduzca 16 valores enteros\n");
for (i=0; i<4; i++)
for (j=0; j<4; j++)
scanf ("%d", *(px+i)+j);
for (i=0; i<4; i++)
{
for (j=0; j<4; j++)
printf("%7d", *(*(px+i)+j));
printf("\n");
}
getch();
}
Ojo es vector y se maneja como matriz corregir en 9 y 10 ver si se deja con un ciclo o 2.
Ejemplo 10
Objetivo del programa: Presentar un arreglo unidimensional de punteros y un puntero a
puntero, introducirle valores e imprimirlo.
#include <stdio.h>
#include <conio.h>
void main() {
int i,j;
int *p[4]; //array de punteros//
int **px=p; //px es un puntero a un puntero//
clrscr();
printf ("Introduzca 16 valores enteros:\n");
for (i=0; i<4; i++)
for (j=0; j<4; j++)
scanf ("%d", &px[i][j]);
for (i=0; i<4; i++)
{
for (j=0; j<4; j++)
printf("%7d",px[i][j]);
//Imprime como array "%7d" deja 7 blancos
ESTRUCTURAS DE DATOS
CICLO II
6
//printf("%7d", *(*(px+i)+j)); //Imprime como puntero
printf("\n");
}
getch();
}
Ejemplo 11
Objetivo del programa: Mostrar las direcciones de memoria y los contenidos de la misma, al
emplear arreglos unidimensionales y aritmética de punteros
#include <stdio.h>
#include <conio.h>
void main() {
int mat[] = {2, 16, -4, 29, 234, 12, 0, 3}, i =0;
system(cls);
puts("Imprimimos las direcciones de memoria y valores contenidos:");
puts("\nDireccción de memoria &mat[i] \t\tContenido mat[i]");
for ( ; i<8 ; i++)
printf("\n\t&mat[%d] = %p \t\t mat[%d] = %d", i,&mat[i], i, mat[i]);
getch();
printf("\n\nRepetimos los resultados empleando notación de punteros:\n");
getch();
puts("\nDireccción de memoria mat + i \t\tContenido *(mat+i)");
for( i=0 ; i<8 ; i++)
printf("\n\tmat+%d = %p \t\t\t *(mat+%d) = %d", i, mat+i, i, *(mat+i));
getch();
}
EJERCICIOS
1. Un programa C contiene la siguiente declaración:
static char *color[6] = {“red”, “green”, “blue”, “white”, “black”, “yellow”};
a) ¿Cuál es el significado de color?
__________________________________________________________________
b) ¿Cuál es el significado de (color+2)?
__________________________________________________________________
c) ¿Cuál es el valor de *color?
__________________________________________________________________
d) ¿Cuál es el valor de *(color + 2)?
__________________________________________________________________
e) ¿Cuál es la diferencia de color[5] y *(color+5)?
2. Escriba el propósito de cada una de las siguientes declaraciones en C:
a) float ( *x ) ( int *a );
____________________________________________________________________
____________________________________________________________________
ESTRUCTURAS DE DATOS
CICLO II
7
b) float ( *x ( int *a ) ) [20];
____________________________________________________________________
____________________________________________________________________
c) float x ( int ( *a ) [] );
____________________________________________________________________
____________________________________________________________________
d) float x ( int *a[] );
____________________________________________________________________
____________________________________________________________________
e) float *x ( int a[] );
____________________________________________________________________
____________________________________________________________________
3. Escriba un programa completo en C, usando notación de punteros en lugar de notación
de arreglos que lea una línea de texto, la guarde en un arreglo, y luego la escriba en
forma inversa. Permita que el tamaño de la línea sea terminada por un retorno de carro
pero que no exceda 80 caracteres.
4. Escriba un programa en C, usando notación de punteros en lugar de notación de
arreglos que lea un arreglo unidimensional de números enteros y aplicando un método
de ordenamiento de vectores los ordene en forma Ascendente.
ESTRUCTURAS DE DATOS
CICLO II
8
Descargar