Documentos de Académico
Documentos de Profesional
Documentos de Cultura
GUÍA DE LABORATORIO
PROGRAMACIÓN DE SISTEMAS
SEMESTRE A
COMPETENCIAS
Diseña responsablemente sistemas componentes o procesos para satisfacer necesidades dentro de restricciones
realistas, económicas, medio ambientales, sociales, políticas, éticas, de salud, de seguridad, manufacturación y
sostenibilidad
Construye responsablemente soluciones siguiendo un proceso adecuado llevando a cabo las pruebas ajustadas a
los recursos disponibles del cliente
Aplica la forma flexible técnicas, métodos, principios, normas, estándares y herramientas de ingeniería necesarias
para la construcción de software e implementación de sistemas de información
Curso: Programación de Sistemas Página: 1
Punteros en C++
Laboratorio
4
I
OBJETIVOS
• La presente práctica de laboratorio tiene como objetivo el uso de punteros en C++.
II
TEMAS A TRATAR
• Introducción
• Variables de Apuntador
• Direcciones Números
• Operadores * y &
• Operador New
III
MARCO TEÓRICO
❖ INTRODUCCIÓN:
Una dirección que se utiliza para nombrar una variable de este modo (dando la
dirección de memoria donde la variable inicia) se llama apuntador porque podemos
pensar que la dirección “apunta” a la variable. La dirección “apunta” a la variable
porque la identifica diciendo dónde está, en lugar de decir qué nombre tiene. Digamos
que una variable está en la posición número 1007; podemos referirnos a ella diciendo
“es la variable que está allá, en la posición 1007”.
Magister Oscar Alberto Ramirez Valdez
Magister Roni Guillermo Apaza Aceituno
Curso: Programación de Sistemas Página: 2
❖ VARIABLES DE APUNTADOR:
double *p;
En general, si queremos declarar una variable que pueda contener apuntadores a otras
variables de un tipo específico, declaramos las variables de apuntador igual que
declaramos una variable ordinaria de ese tipo, pero colocamos un asterisco antes del
nombre de la variable. Por ejemplo, lo siguiente declara las variables p1 y p2 de modo
que puedan contener apuntadores a variables de tipo int; también se declaran dos
variables ordinarias v1 y v2 de tipo int:
Es necesario que haya un asterisco antes de cada una de las variables de apuntador. Si
omitimos el segundo asterisco en la declaración anterior, p2 no será una variable de
apuntador; será una variable ordinaria de tipo int. El asterisco es el mismo símbolo
que hemos estado usando para la multiplicación, pero en este contexto tiene un
significado totalmente distinto.
Sintaxis:
Ejemplo:
p1, contiene la dirección de una variable, como v1, decimos que dicha variable apunta
a la variable v1 o es un apuntador a la variable v1.
❖ DIRECCIONES NÚMEROS:
(Podemos realizar una especie de suma y una especie de resta con apuntadores, pero
no son la suma y resta normales con enteros.)
p1 = &v1;
Ahora tenemos dos formas de referirnos a v1: podemos llamarla v1 o “la variable a la
que p1 apunta”. En C++ la forma de decir “la variable a la que p1 apunta” es *p1.
Éste es el mismo asterisco que usamos al declarar p1, pero ahora tiene otro
significado. Cuando el asterisco se usa de esta manera se le conoce como operador de
desreferenciación, y decimos que la variable de apuntador está desreferenciada.
v1 = 0;
p1 = &v1;
*p1 = 42;
42
42
El símbolo & que usamos para obtener la dirección de una variable es el mismo
símbolo que usamos en una declaración de función para especificar un parámetro de
llamada por referencia. Esto no es una coincidencia. Recuerde que un argumento de
llamada por referencia se implementa dando la dirección del argumento a la función
invocadora. Así pues, estos dos usos del símbolo & son básicamente el mismo. Sin
embargo, hay ciertas diferencias pequeñas en la forma de uso, así que los
consideraremos dos usos distintos (aunque íntimamente relacionados) del símbolo &.
❖ OPERADORES * y &:
double *p, v;
p= &v;
*p = 9.99;
p2 = p1;
Asegúrese de no confundir
p1 = p2;
con
*p1 = *p2;
Puesto que podemos usar un de apuntador para referirnos a una variable, el programa
puede manipular variables, aunque éstas carezcan de identificadores que las nombren.
Podemos usar el operador new para crear variables sin identificadores que sean sus
nombres. Hacemos referencia a estas variables sin nombre mediante apuntadores. Por
ejemplo, lo siguiente crea una nueva variable de tipo int y asigna a la variable de
apuntador p1 la dirección de esta nueva variable (es decir, p1 apunta a esta nueva
variable sin nombre):
p1 = new int;
Podemos usar *p1 para referirnos a esta nueva variable (es decir, la variable a la que
p1 apunta). Podemos hacer con esta variable sin nombre lo mismo que con cualquier
otra variable de tipo int. Por ejemplo, lo que sigue lee un valor de tipo int del teclado
y lo coloca en la variable sin nombre, suma 7 al valor y luego despliega el nuevo valor
en la pantalla:
*p1 = *p1 + 7;
El operador new produce una nueva variable sin nombre y devuelve un apuntador que
apunta a esta nueva variable.
❖ OPERADOR NEW:
El operador new crea una nueva variable dinámica del tipo que se especifica y
devuelve un apuntador que apunta a esta nueva variable. Por ejemplo, lo que sigue
crea una variable dinámica nueva del tipo MiTipo y deja a la variable del apuntador p
apuntando a esa nueva variable.
MiTipo *p;
p = new MiTipo;
int *n;
MiTipo *apuntMt;
El estándar de C++ estipula que, si no hay suficiente memoria desocupada para crear
la nueva variable, la acción predeterminada del operador new es terminar el programa.
#include <iostream>
using namespace std;
int main()
{
int *p1, *p2;
p1 = new int;
*p1 = 42;
p2 = p1;
cout << "*p1 == " << *p1 << endl;
cout << "*p2 == " << *p2 << endl;
*p2 = 53;
cout << "*p1 == " << *p1 << endl;
cout << "*p2 == " << *p2 << endl;
p1 = new int;
*p1 = 88;
cout << "*p1 == " << *p1 << endl;
cout << "*p2 == " << *p2 << endl;
cout << "Este es un ejemplo de uso de apuntadores!\n";
return 0;
}
IV
ACTIVIDADES
• Consideraciones: Instalar un IDE para la programación de C++. Puede ser Zinjal,
Visual Studio 2019, entre otros.
• ACTIVIDAD 2.
• ACTIVIDAD 2.
V
EJERCICIOS RESUELTOS
Magister Oscar Alberto Ramirez Valdez
Magister Roni Guillermo Apaza Aceituno
Curso: Programación de Sistemas Página: 8
#include <bits/stdc++.h>
using namespace std;
void alumnos(){
int var = 20;
int *ptr; //declaramos una variable puntero
ptr = &var;
//el tipo de dato var y ptr son lo mismo
//asignamos la direccion de una a un puntero
cout << "Valor para ptr = " << ptr << "\n";
cout << "Valor para var = " << var << "\n";
cout << "Valor para *ptr = " << *ptr << "\n";
}
//funcion principal
int main()
{
alumnos();
}
#include <bits/stdc++.h>
using namespace std;
//pasando por valor
int cuadrado1(int n)
{
//Dirección de n en cuadrado1 no es la misma en n1 en main()
cout << "address de n1 en cuadrado1(): "<< &n << "\n";
alumnos();
}
#include <bits/stdc++.h>
using namespace std;
void cuadrado2(int *n)
{
//dirección de n en cuadrado2() es la misma de n2 en la función principal()
cout << "dirección de n2 en cuadrado2(): " << n << "\n";
//Rereferencias explicitamente para obtener el valor al cual se apunta
*n *= *n;
}
void alumnos()
{
//llamda por referencia con punteros como argumentos
int n2=8;
cout << "dirección de n2 en la función principal(): " << &n2 << "\n";
cuadrado2(&n2);
cout << "cuadrado de n2: " << n2 << "\n";
cout << "Cambio visto en n2: " << n2 << "\n";
}
int main()
{
alumnos();
}
#include <bits/stdc++.h>
using namespace std;
//Pasar por referencia con argumentos como referencia
void cuadrado3(int &n)
{
//dirección de n en el cuadrado3() es la misma que n3 en la función
principal
cout << "dirección de n3 en cuadrado3(): "<< &n << "\n";
//Implicito rereferenciado (sin "*")
n *= n;
}
void alumnos()
{
//llamada por referencia con argumentos como referencia
int n3 =8;
cout << "dirección de n3 en la función principal: " << &n3 << "\n";
cuadrado3(n3);
cout << "Cuadrado de n3: " << n3 << "\n";
cout << "Cambio reflejado en n3: " << n3 << "\n";
}
int main()
{
alumnos();
}
#include <iostream>
using namespace std;
int main()
{
int x = 10;
// ref es una referencia hacia x
int& ref = x;
// valor de x es ahora cambiado a 20
ref = 20;
cout << "x = " << x << endl;
// valor de x es ahora cambiado a 30
x = 30;
cout << "ref = " << ref << endl;
return 0;
}
#include <iostream>
using namespace std;
void swap (int& primero, int& segundo)
{
int temporal = primero;
primero = segundo;
segundo = temporal;
}
int main()
{
int a = 2, b = 3;
swap( a,b );
cout<<a<<" "<<b;
return 0;
}
#include <iostream>
using namespace std;
int main() {
int i = 10; //varialbe simple
int *p=&i;//puntero simple
int **pt=&p; //doble puntero
int ***ptr=&pt; //triple puntero
//Todos los punteros anteriores son diferentes
cout << "i=" << i << "\t" << "p=" << p << "\t" << "pt= " << pt << "\t" <<
"ptr= " << ptr << "\n";
}
#include <iostream>
using namespace std;
int main(){
int a = 5; // una simple variable
int &S = a;
int &S0 = S;
int &S1 = S0;
cout << "a = "<< a << "\t" << "S = " << S << "\t" << "S0 = " << S0 << "\t"
<< "S1 = " << S1 << "\n";
//Todos las referencias no son diferentes en sus valores
//Ellas hacen referencia a la misma variable
}
• EJERCICIO 9. Crea un programa en C++ que permita utilizar un arreglo para ser
asignado a una variable puntero
#include <bits/stdc++.h>
using namespace std;
void alumnos()
{
//declaramos un arreglo
int val[3] = { 5, 10, 20 };
• EJERCICIO 10. Crear un programa en C++ donde la variable puntero ptr reciba
un arreglo y se comporte como un arreglo al ser recorrido sin ser declarado como
arreglo
#include <bits/stdc++.h>
using namespace std;
void alumnos()
{
//declaramos el arreglo
int v[3] = { 10, 100, 200};
//declaramos una variable puntero
int *ptr;
//asignamos la dirección de v[0] para ptr
ptr = v;
for (int i = 0; i < 3; i++)
{
cout << "Valor para ptr = " << ptr << "\n";
cout << "Valor para *ptr = " << *ptr << "\n";
//incrementando el puntero a 1
ptr++;
}
}
int main()
{
alumnos();
}
#include <iostream>
using namespace std;
int main()
{
int arr[] = { 10, 20, 30, 40, 50, 60 };
int* ptr = arr;
//usaremos la función sizof para mostrar el numero de elementos en arr[]
cout << "Size of arr[] " << sizeof(arr) << "\n";
//El tamaño de un puntero es impreso, el cual es el mismo que todos los
//tipos de punteros (char *, void *, etc)
cout << "Size of ptr " << sizeof(ptr) ;
return 0;
}
• EJERCICIO 12. Crear un programa en c++ que muestre que está prohibido
asignar cualquier dirección a una variable arreglo, mostrando un error al
compilarlo en la pantalla
#include <iostream>
using namespace std;
int main()
{
int arr[] = {10,20}, x =10;
int *ptr = &x; //esto esta bien
arr = &x; // esto esta mal
return 0;
}
• EJERCICIO 13. Crear un programa en c++ que muestre que el primer elemento
que muestra una variable puntero con el contenido de un arreglo siempre será el
primero elemento de dicho arreglo
#include <iostream>
using namespace std;
int main()
{
int arr[] = { 10, 20, 30, 40, 50, 60 };
//asignamos la dirección del arreglo al puntero
int* ptr = arr;
cout << "Valor del primer elemento es " << *ptr << endl;
cout << "Valor del arreglo es " << arr << endl;
return 0;
}
#include <iostream>
using namespace std;
int main()
{
int arr[] = { 10, 20, 30, 40, 50, 60 };
int* ptr = arr;
cout << "arr[2] = " << arr[2] << "\n";
cout << "*(arr + 2) = " << *(arr + 2) << "\n";
cout << "ptr[2] = " << ptr[2] << "\n";
cout << "*(ptr + 2) = " << *(ptr + 2 ) << "\n";
return 0;
}
• EJERCICIO 15. Escribir un programa en c++ que muestre que los parámetros de
los arreglos siempre son pasados como punteros aun cuando se usen los corchetes
#include <bits/stdc++.h>
using namespace std;
int fun(int ptr[])
{
int x = 10;
//El tamaño de un puntero es impreso
cout << "sizeof(ptr) = " << (int)sizeof(*ptr) << endl;
//Esto esta permitido por ptr es un puntero, no un arreglo
ptr = &x;
cout << "*ptr = " << *ptr;
return 0;
}
//codigo principal
int main()
{
int arr[] = { 20, 20, 30, 40, 50, 60 };
//tamaño de un arreglo
cout << "sizeof(arr) = " << (int)sizeof(arr) << endl;
fun(arr);
return 0;
}
• EJERCICIO 16. Crear un programa en C++ que muestre como se puede apuntar
a valores que no tienen tipo
#include <bits/stdc++.h>
using namespace std;
void incrementar(void *data, int ptrsize)
{
if(ptrsize == sizeof(char))
{
char *ptrchar;
//Casteamos el dato par aun puntero char
ptrchar = (char*)data;
//Incrementamos el valor char guardado a *ptrchar en 1
(*ptrchar)++;
cout << "*puntos datos para un char" << "\n";
}
else if(ptrsize == sizeof(int))
{
int *ptrint;
//Casteamos datos para un puntero int
ptrint = (int*)data;
//Incrementamos el entero alojado a *ptrchar en 1
(*ptrint)++;
cout << "*puntos datos para un int" << "\n";
}
}
void alumno()
{
//declaramos un caracter
char c='x';
//declaramos un entero
int i=10;
//llamamos a una función para incrementar usando un dirección char o
int respectivamente
incrementar(&c,sizeof(c));
cout << "El nuevo valor de c es: " << c << "\n";
incrementar(&i,sizeof(i));
cout << "El nuevo valor de i es: " << i << "\n";
}
//programa principal
int main()
{
alumno();
}
#include <bits/stdc++.h>
using namespace std;
void fun(int n, int* cuadrado, double* raiz_cuadrada)
{
*cuadrado = n * n;
*raiz_cuadrada = sqrt(n);
}
int main()
{
int n = 100;
Magister Oscar Alberto Ramirez Valdez
Magister Roni Guillermo Apaza Aceituno
Curso: Programación de Sistemas Página: 16
#include <iostream>
using namespace std;
int* createArr(int n)
{
return new int[n];
}
int main()
{
int* pt = createArr(10);
cout << pt << endl;
cout << *pt << endl;
return 0;
}
• EJERCICIO 19. Crear un programa en C++ que pueda utilizar el operador new
sobre el tipo entero y asignarlo a un puntero
#include <iostream>
using namespace std;
int main()
{
//Inicializamos con el operador new()
int *n = new int(10);
cout << *n;
//getchar();
return 0;
}
• EJERCICIO 20. Crear un programa en C++ que pueda utilizar el operador new
para ingresar un valor por teclado y mostrarlo en pantalla y después borrarlo
utilizando la función delete
#include <bits/stdc++.h>
using namespace std;
main()
{
VI
EJERCICIOS PROPUESTOS
• EJERCICIO 1.
• EJERCICIO 2.
El juego del ahorcado se juega con dos personas (o una persona y una
computadora). Un jugador selecciona una palabra y el otro jugador trata de
adivinar la palabra adivinando las letras individuales. Diseñar un programa para
jugar al ahorcado.
• EJERCICIO 3.
Se dice que una matriz tiene un punto de silla si alguna posición de la matriz es el
menor valor de su fila, y a la vez el mayor de su columna. Escribir un programa
que tenga como entrada una matriz de números reales, y calcular la posición de un
punto de silla (si es que existe).
• EJERCICIO 4.
Se desea saber:
a- Cantidad total de habitantes del complejo
b- Cantidad promedio de habitantes por piso de cada torre
c- Cantidad promedio de habitantes por torre
• EJERCICIO 5.
• EJERCICIO 6.
Sea A una matriz de tamaño NxN, implemente un programa que dado un menú de
opciones resuelva:
• La transpuesta de A (At).
• Si A es simétrica o antisimétrica.
• Si A es una matriz triangular superior o triangular inferior.
VII
CUESTIONARIO
• ¿Los punteros se pueden usar en estructuras de datos, diga un ejemplo?
• ¿Los punteros pueden ser utilizados en programación orientada a objetos?
VIII
BIBLIOGRAFÍA
[1] P.J. Deitel and H.M. Deitel, “Cómo Programar en C++”, México, Ed. Pearson
Educación, 2009
[2] B. Stroustrup, “El Lenguaje de Programación C++”, Madrid, Adisson Pearson
Educación, 2002
[3] B. Eckel, “Thinking in C++”, Prentice Hall, 2000